From 9e18dfe2775011ad8f506582086ab165bc0cfaa2 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 16 Nov 2013 16:59:07 +0400 Subject: [PATCH 01/55] MIPS grub_machine_get_bootlocation arguments are used --- ChangeLog | 5 +++++ grub-core/kern/mips/arc/init.c | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index dae716056..bba81dba4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-16 Andrey Borzenkov + + * grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation): + Remove "unused" attribute from arguments, they are used. + 2013-11-15 Colin Watson * .gitignore: Only ignore grub-mk* at the top level. diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index f12026e95..cb6c22848 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -355,8 +355,7 @@ get_device_name_iter (grub_disk_t disk __attribute__ ((unused)), } void -grub_machine_get_bootlocation (char **device __attribute__ ((unused)), - char **path __attribute__ ((unused))) +grub_machine_get_bootlocation (char **device, char **path) { char *loaddev = boot_location; char *pptr, *partptr; From c2fdb33116c830fce0ecea7dc0b4aa97e17c3a3a Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 16 Nov 2013 17:00:59 +0400 Subject: [PATCH 02/55] document cmdpath environment variable --- ChangeLog | 4 ++++ docs/grub.texi | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/ChangeLog b/ChangeLog index bba81dba4..a74265abf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-16 Andrey Borzenkov + + * docs/grub.texi (Environment): Document cmdpath. + 2013-11-16 Andrey Borzenkov * grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation): diff --git a/docs/grub.texi b/docs/grub.texi index 0a9670f5b..de72d0cce 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -2989,6 +2989,7 @@ These variables have special meaning to GRUB. * biosnum:: * check_signatures:: * chosen:: +* cmdpath:: * color_highlight:: * color_normal:: * debug:: @@ -3058,6 +3059,16 @@ the titles of each of the submenus starting from the top level followed by the title of the menu entry itself, separated by @samp{>}. +@node cmdpath +@subsection cmdpath + +The location from which @file{core.img} was loaded as an absolute +directory name (@pxref{File name syntax}). This is set by GRUB at +startup based on information returned by platform firmware. Not every +platform provides this information and some may return only device +without path name. + + @node color_highlight @subsection color_highlight From 31c0cd43629b7395eb113e5679bd41dbebc1969c Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 16 Nov 2013 17:03:20 +0400 Subject: [PATCH 03/55] restore -nostdlib for libgcc symbols tests Commit 24f4e57c4684471da088c504dec0380886eece0c plugged leakage of CFLAGS between individual tests, which broke test for libgcc symbols. It needs -nostdlib which was set in previous test and inherited before. Set it explicitly. --- ChangeLog | 4 ++++ configure.ac | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a74265abf..f8bcd188d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-16 Andrey Borzenkov + + * configure.ac: Restore -nostdlib for libgcc symbols tests. + 2013-11-16 Andrey Borzenkov * docs/grub.texi (Environment): Document cmdpath. diff --git a/configure.ac b/configure.ac index 2c4f019f6..18429103b 100644 --- a/configure.ac +++ b/configure.ac @@ -815,9 +815,9 @@ LIBS="$TARGET_LIBGCC" grub_ASM_USCORE if test "x$TARGET_APPLE_LINKER" = x0 ; then if test x$grub_cv_asm_uscore = xyes; then -CFLAGS="$TARGET_CFLAGS -Wl,--defsym,_abort=_main" +CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,_abort=_main" else -CFLAGS="$TARGET_CFLAGS -Wl,--defsym,abort=main" +CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,abort=main" fi fi From 593865b90734ffb462ae13e59d0e1190aaa64d4f Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Sat, 16 Nov 2013 12:15:53 +0000 Subject: [PATCH 04/55] arm: fix u-boot port syscall interface va_arg handling Commit c9cd02c broke the u-boot syscall API for va_args that spill over to the stack, causing the disk support to stop working. This patch resolves the problem, while keeping the new, cleaner transition_space handling. --- ChangeLog | 4 ++++ grub-core/kern/arm/uboot/startup.S | 11 ++--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8bcd188d..c86a2749e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-16 Leif Lindholm + + * grub-core/kern/arm/uboot/startup.S: fix grub_uboot_syscall va_arg + handling 2013-11-16 Andrey Borzenkov * configure.ac: Restore -nostdlib for libgcc symbols tests. diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/uboot/startup.S index f54b14b57..df1e32928 100644 --- a/grub-core/kern/arm/uboot/startup.S +++ b/grub-core/kern/arm/uboot/startup.S @@ -131,11 +131,6 @@ FUNCTION(grub_uboot_syscall) str r8, transition_space str lr, transition_space + 4 str r9, transition_space + 8 - str sp, transition_space + 12 - - sub sp, sp, #0x20 - lsr sp, sp, #3 - lsl sp, sp, #3 ldr r8, gd_backup ldr r9, gd_backup + 4 @@ -147,7 +142,6 @@ FUNCTION(grub_uboot_syscall) ldr r8, transition_space ldr lr, transition_space + 4 ldr r9, transition_space + 8 - ldr sp, transition_space + 12 bx lr @@ -166,8 +160,8 @@ entry_state_end: .long 0 @ r6 .long 0 @ r7 gd_backup: - .long 0 @ r8 - U-Boot global data pointer - .long 0 @ r9 + .long 0 @ r8 - U-Boot global data pointer up to 2013-09-21 + .long 0 @ r9 - U-Boot global data pointer 2013-09-21 onwards .long 0 @ r10 .long 0 @ r11 VARIABLE(grub_uboot_search_hint)@ U-Boot stack pointer - @@ -180,7 +174,6 @@ transition_space: .long 0 @ r8 .long 0 @ lr .long 0 @ r9 - .long 0 @ sp VARIABLE(grub_uboot_syscall_ptr) .long 0 @ From 7b5d51d837c6fe88fe94198f41a654a03e4d71de Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 16:00:42 +0100 Subject: [PATCH 05/55] Decrease stack usage in JFS. We have only 92K of stack and using over 4K per frame is wasteful * grub-core/fs/jfs.c (getblk): Allocate on heap rather than on stack. Note: this function is recursive. (grub_jfs_read_inode): Read only part we care about. --- ChangeLog | 11 +++++++++++ grub-core/fs/jfs.c | 35 ++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index c86a2749e..3022acf6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,18 @@ +2013-11-16 Vladimir Serbinenko + + Decrease stack usage in JFS. + + We have only 92K of stack and using over 4K per frame is wasteful + + * grub-core/fs/jfs.c (getblk): Allocate on heap rather than on + stack. Note: this function is recursive. + (grub_jfs_read_inode): Read only part we care about. + 2013-11-16 Leif Lindholm * grub-core/kern/arm/uboot/startup.S: fix grub_uboot_syscall va_arg handling + 2013-11-16 Andrey Borzenkov * configure.ac: Restore -nostdlib for libgcc symbols tests. diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 062501492..3251baa6e 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -72,10 +72,13 @@ struct grub_jfs_extent grub_uint32_t blk2; } __attribute__ ((packed)); +#define GRUB_JFS_IAG_INODES_OFFSET 3072 +#define GRUB_JFS_IAG_INODES_COUNT 128 + struct grub_jfs_iag { - grub_uint8_t unused[3072]; - struct grub_jfs_extent inodes[128]; + grub_uint8_t unused[GRUB_JFS_IAG_INODES_OFFSET]; + struct grub_jfs_extent inodes[GRUB_JFS_IAG_INODES_COUNT]; } __attribute__ ((packed)); @@ -283,20 +286,25 @@ getblk (struct grub_jfs_treehead *treehead, if (found != -1) { + grub_int64_t ret = -1; struct { struct grub_jfs_treehead treehead; struct grub_jfs_tree_extent extents[254]; - } tree; + } *tree; - if (grub_disk_read (data->disk, - ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2)) - << (grub_le_to_cpu16 (data->sblock.log2_blksz) - - GRUB_DISK_SECTOR_BITS), 0, - sizeof (tree), (char *) &tree)) + tree = grub_zalloc (sizeof (*tree)); + if (!tree) return -1; - return getblk (&tree.treehead, &tree.extents[0], data, blk); + if (!grub_disk_read (data->disk, + ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2)) + << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS), 0, + sizeof (*tree), (char *) tree)) + ret = getblk (&tree->treehead, &tree->extents[0], data, blk); + grub_free (tree); + return ret; } return -1; @@ -316,7 +324,7 @@ static grub_err_t grub_jfs_read_inode (struct grub_jfs_data *data, grub_uint32_t ino, struct grub_jfs_inode *inode) { - struct grub_jfs_iag iag; + struct grub_jfs_extent iag_inodes[GRUB_JFS_IAG_INODES_COUNT]; grub_uint32_t iagnum = ino / 4096; unsigned inoext = (ino % 4096) / 32; unsigned inonum = (ino % 4096) % 32; @@ -330,11 +338,12 @@ grub_jfs_read_inode (struct grub_jfs_data *data, grub_uint32_t ino, /* Read in the IAG. */ if (grub_disk_read (data->disk, iagblk << (grub_le_to_cpu16 (data->sblock.log2_blksz) - - GRUB_DISK_SECTOR_BITS), 0, - sizeof (struct grub_jfs_iag), &iag)) + - GRUB_DISK_SECTOR_BITS), + GRUB_JFS_IAG_INODES_OFFSET, + sizeof (iag_inodes), &iag_inodes)) return grub_errno; - inoblk = grub_le_to_cpu32 (iag.inodes[inoext].blk2); + inoblk = grub_le_to_cpu32 (iag_inodes[inoext].blk2); inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS); inoblk += inonum; From deaa7052c5161f54b42da0c887d08fddfa1130d7 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 16:03:28 +0100 Subject: [PATCH 06/55] Decrease stack usage in BtrFS. We have only 92K of stack and using over 4K per frame is wasteful * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Allocate on heap rather than stack. --- ChangeLog | 9 +++++++++ grub-core/fs/btrfs.c | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3022acf6e..9e48e3932 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2013-11-16 Vladimir Serbinenko + + Decrease stack usage in BtrFS. + + We have only 92K of stack and using over 4K per frame is wasteful + + * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Allocate on heap + rather than stack. + 2013-11-16 Vladimir Serbinenko Decrease stack usage in JFS. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 49f11cc3c..a60852756 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -911,7 +911,6 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, { grub_uint32_t total_size, cblock_size; grub_size_t ret = 0; - unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; char *ibuf0 = ibuf; total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); @@ -955,13 +954,21 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) { grub_size_t to_copy = GRUB_BTRFS_LZO_BLOCK_SIZE - off; + grub_uint8_t *buf; if (to_copy > osize) to_copy = osize; + buf = grub_malloc (GRUB_BTRFS_LZO_BLOCK_SIZE); + if (!buf) + return -1; + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, NULL) != LZO_E_OK) - return -1; + { + grub_free (buf); + return -1; + } if (to_copy > usize) to_copy = usize; @@ -972,6 +979,8 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, obuf += to_copy; ibuf += cblock_size; off = 0; + + grub_free (buf); continue; } From 1a454efe89ea84794d1e658a357128163297a6d9 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 16:03:28 +0100 Subject: [PATCH 07/55] Decrease stack usage in BtrFS. We have only 92K of stack and using over 4K per frame is wasteful * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Allocate on heap rather than stack. --- ChangeLog | 9 +++++++++ grub-core/fs/btrfs.c | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3022acf6e..9e48e3932 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2013-11-16 Vladimir Serbinenko + + Decrease stack usage in BtrFS. + + We have only 92K of stack and using over 4K per frame is wasteful + + * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Allocate on heap + rather than stack. + 2013-11-16 Vladimir Serbinenko Decrease stack usage in JFS. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 49f11cc3c..a60852756 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -911,7 +911,6 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, { grub_uint32_t total_size, cblock_size; grub_size_t ret = 0; - unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; char *ibuf0 = ibuf; total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); @@ -955,13 +954,21 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) { grub_size_t to_copy = GRUB_BTRFS_LZO_BLOCK_SIZE - off; + grub_uint8_t *buf; if (to_copy > osize) to_copy = osize; + buf = grub_malloc (GRUB_BTRFS_LZO_BLOCK_SIZE); + if (!buf) + return -1; + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, NULL) != LZO_E_OK) - return -1; + { + grub_free (buf); + return -1; + } if (to_copy > usize) to_copy = usize; @@ -972,6 +979,8 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, obuf += to_copy; ibuf += cblock_size; off = 0; + + grub_free (buf); continue; } From e6a6182d95d26871a7d34af66899ae2b0f9b5b75 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 16:16:48 +0100 Subject: [PATCH 08/55] Decrease stack usage in mdraid 0.9x. We have only 92K of stack and using over 4K per frame is wasteful * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Allocate on heap rather than stack. --- ChangeLog | 9 +++++ grub-core/disk/mdraid_linux.c | 71 ++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e48e3932..0bbc2ebc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2013-11-16 Vladimir Serbinenko + + Decrease stack usage in mdraid 0.9x. + + We have only 92K of stack and using over 4K per frame is wasteful + + * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Allocate on heap + rather than stack. + 2013-11-16 Vladimir Serbinenko Decrease stack usage in BtrFS. diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index f408fd37e..eb679f5ce 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -184,9 +184,10 @@ grub_mdraid_detect (grub_disk_t disk, { grub_disk_addr_t sector; grub_uint64_t size; - struct grub_raid_super_09 sb; + struct grub_raid_super_09 *sb = NULL; grub_uint32_t *uuid; grub_uint32_t level; + struct grub_diskfilter_vg *ret; /* The sector where the mdraid 0.90 superblock is stored, if available. */ size = grub_disk_get_size (disk); @@ -195,27 +196,31 @@ grub_mdraid_detect (grub_disk_t disk, return NULL; sector = NEW_SIZE_SECTORS (size); - if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb)) + sb = grub_malloc (sizeof (*sb)); + if (!sb) return NULL; + if (grub_disk_read (disk, sector, 0, SB_BYTES, sb)) + goto fail; + /* Look whether there is a mdraid 0.90 superblock. */ - if (sb.md_magic != grub_cpu_to_md32_compile_time (SB_MAGIC)) + if (sb->md_magic != grub_cpu_to_md32_compile_time (SB_MAGIC)) /* not 0.9x raid. */ - return NULL; + goto fail; - if (sb.major_version != grub_cpu_to_md32_compile_time (0) - || sb.minor_version != grub_cpu_to_md32_compile_time (90)) + if (sb->major_version != grub_cpu_to_md32_compile_time (0) + || sb->minor_version != grub_cpu_to_md32_compile_time (90)) /* Unsupported version. */ - return NULL; + goto fail; - /* No need for explicit check that sb.size is 0 (unspecified) since + /* No need for explicit check that sb->size is 0 (unspecified) since 0 >= non-0 is false. */ - if (((grub_disk_addr_t) grub_md_to_cpu32 (sb.size)) * 2 >= size) - return NULL; + if (((grub_disk_addr_t) grub_md_to_cpu32 (sb->size)) * 2 >= size) + goto fail; /* FIXME: Check the checksum. */ - level = grub_md_to_cpu32 (sb.level); + level = grub_md_to_cpu32 (sb->level); /* Multipath. */ if ((int) level == -4) level = 1; @@ -225,37 +230,43 @@ grub_mdraid_detect (grub_disk_t disk, { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unsupported RAID level: %d", level); - return NULL; + goto fail; } - if (grub_md_to_cpu32 (sb.this_disk.number) == 0xffff - || grub_md_to_cpu32 (sb.this_disk.number) == 0xfffe) + if (grub_md_to_cpu32 (sb->this_disk.number) == 0xffff + || grub_md_to_cpu32 (sb->this_disk.number) == 0xfffe) /* Spares aren't implemented. */ - return NULL; + goto fail; uuid = grub_malloc (16); if (!uuid) - return NULL; + goto fail; - uuid[0] = grub_swap_bytes32 (sb.set_uuid0); - uuid[1] = grub_swap_bytes32 (sb.set_uuid1); - uuid[2] = grub_swap_bytes32 (sb.set_uuid2); - uuid[3] = grub_swap_bytes32 (sb.set_uuid3); + uuid[0] = grub_swap_bytes32 (sb->set_uuid0); + uuid[1] = grub_swap_bytes32 (sb->set_uuid1); + uuid[2] = grub_swap_bytes32 (sb->set_uuid2); + uuid[3] = grub_swap_bytes32 (sb->set_uuid3); *start_sector = 0; id->uuidlen = 0; - id->id = grub_md_to_cpu32 (sb.this_disk.number); + id->id = grub_md_to_cpu32 (sb->this_disk.number); char buf[32]; - grub_snprintf (buf, sizeof (buf), "md%d", grub_md_to_cpu32 (sb.md_minor)); - return grub_diskfilter_make_raid (16, (char *) uuid, - grub_md_to_cpu32 (sb.raid_disks), buf, - (sb.size) ? ((grub_disk_addr_t) - grub_md_to_cpu32 (sb.size)) * 2 - : sector, - grub_md_to_cpu32 (sb.chunk_size) >> 9, - grub_md_to_cpu32 (sb.layout), - level); + grub_snprintf (buf, sizeof (buf), "md%d", grub_md_to_cpu32 (sb->md_minor)); + ret = grub_diskfilter_make_raid (16, (char *) uuid, + grub_md_to_cpu32 (sb->raid_disks), buf, + (sb->size) ? ((grub_disk_addr_t) + grub_md_to_cpu32 (sb->size)) * 2 + : sector, + grub_md_to_cpu32 (sb->chunk_size) >> 9, + grub_md_to_cpu32 (sb->layout), + level); + grub_free (sb); + return ret; + + fail: + grub_free (sb); + return NULL; } static struct grub_diskfilter grub_mdraid_dev = { From 4f84ae0ec8a290aefb989de24552dbb23e65a6f1 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 16:34:51 +0100 Subject: [PATCH 09/55] Decrease stack usage in signature verification. We have only 92K of stack and using over 4K per frame is wasteful * grub-core/commands/verify.c (grub_load_public_key): Allocate on heap rather than stack. (grub_verify_signature_real): Likewise. --- ChangeLog | 10 +++++++++ grub-core/commands/verify.c | 45 ++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bbc2ebc3..acf26a955 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2013-11-16 Vladimir Serbinenko + + Decrease stack usage in signature verification. + + We have only 92K of stack and using over 4K per frame is wasteful + + * grub-core/commands/verify.c (grub_load_public_key): Allocate on heap + rather than stack. + (grub_verify_signature_real): Likewise. + 2013-11-16 Vladimir Serbinenko Decrease stack usage in mdraid 0.9x. diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c index 04960c5d6..3e61c2257 100644 --- a/grub-core/commands/verify.c +++ b/grub-core/commands/verify.c @@ -198,17 +198,16 @@ free_pk (struct grub_public_key *pk) grub_free (pk); } +#define READBUF_SIZE 4096 + struct grub_public_key * grub_load_public_key (grub_file_t f) { grub_err_t err; struct grub_public_key *ret; struct grub_public_subkey **last = 0; - void *fingerprint_context; - - fingerprint_context = grub_zalloc (GRUB_MD_SHA1->contextsize); - if (!fingerprint_context) - return NULL; + void *fingerprint_context = NULL; + grub_uint8_t *buffer = NULL; ret = grub_zalloc (sizeof (*ret)); if (!ret) @@ -217,6 +216,12 @@ grub_load_public_key (grub_file_t f) return NULL; } + buffer = grub_zalloc (READBUF_SIZE); + fingerprint_context = grub_zalloc (GRUB_MD_SHA1->contextsize); + + if (!buffer || !fingerprint_context) + goto fail; + last = &ret->subkeys; while (1) @@ -304,7 +309,6 @@ grub_load_public_key (grub_file_t f) { grub_uint16_t l; grub_size_t lb; - grub_uint8_t buffer[4096]; if (grub_file_read (f, &l, sizeof (l)) != sizeof (l)) { grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); @@ -312,7 +316,7 @@ grub_load_public_key (grub_file_t f) } lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT; - if (lb > sizeof (buffer) - sizeof (grub_uint16_t)) + if (lb > READBUF_SIZE - sizeof (grub_uint16_t)) { grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); goto fail; @@ -348,6 +352,7 @@ grub_load_public_key (grub_file_t f) fail: free_pk (ret); grub_free (fingerprint_context); + grub_free (buffer); return NULL; } @@ -486,10 +491,12 @@ grub_verify_signature_real (char *buf, grub_size_t size, gcry_mpi_t hmpi; grub_uint64_t keyid = 0; struct grub_public_subkey *sk; + grub_uint8_t *readbuf = NULL; context = grub_zalloc (hash->contextsize); - if (!context) - return grub_errno; + readbuf = grub_zalloc (READBUF_SIZE); + if (!context || !readbuf) + goto fail; hash->init (context); if (buf) @@ -497,8 +504,7 @@ grub_verify_signature_real (char *buf, grub_size_t size, else while (1) { - grub_uint8_t readbuf[4096]; - r = grub_file_read (f, readbuf, sizeof (readbuf)); + r = grub_file_read (f, readbuf, READBUF_SIZE); if (r < 0) goto fail; if (r == 0) @@ -510,8 +516,8 @@ grub_verify_signature_real (char *buf, grub_size_t size, hash->write (context, &v4, sizeof (v4)); while (rem) { - grub_uint8_t readbuf[4096]; - r = grub_file_read (sig, readbuf, rem < (grub_ssize_t) sizeof (readbuf) ? rem : (grub_ssize_t) sizeof (readbuf)); + r = grub_file_read (sig, readbuf, + rem < READBUF_SIZE ? rem : READBUF_SIZE); if (r < 0) goto fail; if (r == 0) @@ -527,11 +533,10 @@ grub_verify_signature_real (char *buf, grub_size_t size, if (r != sizeof (unhashed_sub)) goto fail; { - grub_uint8_t readbuf[4096]; grub_uint8_t *ptr; grub_uint32_t l; rem = grub_be_to_cpu16 (unhashed_sub); - if (rem > (int) sizeof (readbuf)) + if (rem > READBUF_SIZE) goto fail; r = grub_file_read (sig, readbuf, rem); if (r != rem) @@ -576,24 +581,23 @@ grub_verify_signature_real (char *buf, grub_size_t size, { grub_uint16_t l; grub_size_t lb; - grub_uint8_t buffer[4096]; grub_dprintf ("crypt", "alive\n"); if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l)) goto fail; grub_dprintf ("crypt", "alive\n"); lb = (grub_be_to_cpu16 (l) + 7) / 8; grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l)); - if (lb > sizeof (buffer) - sizeof (grub_uint16_t)) + if (lb > READBUF_SIZE - sizeof (grub_uint16_t)) goto fail; grub_dprintf ("crypt", "alive\n"); - if (grub_file_read (sig, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) + if (grub_file_read (sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) goto fail; grub_dprintf ("crypt", "alive\n"); - grub_memcpy (buffer, &l, sizeof (l)); + grub_memcpy (readbuf, &l, sizeof (l)); grub_dprintf ("crypt", "alive\n"); if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP, - buffer, lb + sizeof (grub_uint16_t), 0)) + readbuf, lb + sizeof (grub_uint16_t), 0)) goto fail; grub_dprintf ("crypt", "alive\n"); } @@ -631,6 +635,7 @@ grub_verify_signature_real (char *buf, grub_size_t size, fail: grub_free (context); + grub_free (readbuf); if (!grub_errno) return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); return grub_errno; From 080603f0b0d786017b021fd280f338966fa0cc85 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 16:37:59 +0100 Subject: [PATCH 10/55] Decrease stack usage in lexer. We have only 92K of stack and using over 4K per frame is wasteful * grub-core/script/yylex.l (yyalloc), (yyfree), (yyrealloc): Declare as macros so that compiler would remove useless structure on stack. Better solution would be to fix flex not to put this structure on the stack but flex is external program. --- ChangeLog | 11 +++++++++++ grub-core/script/yylex.l | 28 +++------------------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index acf26a955..7b5a8125b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2013-11-16 Vladimir Serbinenko + + Decrease stack usage in lexer. + + We have only 92K of stack and using over 4K per frame is wasteful + + * grub-core/script/yylex.l (yyalloc), (yyfree), (yyrealloc): Declare + as macros so that compiler would remove useless structure on stack. + Better solution would be to fix flex not to put this structure on + the stack but flex is external program. + 2013-11-16 Vladimir Serbinenko Decrease stack usage in signature verification. diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 6c61f855f..9c2cfe115 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -31,9 +31,9 @@ #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wsign-compare" -#define yyfree grub_lexer_yyfree -#define yyalloc grub_lexer_yyalloc -#define yyrealloc grub_lexer_yyrealloc +#define yyalloc(size, scanner) (grub_malloc((size))) +#define yyfree(ptr, scanner) (grub_free((ptr))) +#define yyrealloc(ptr, size, scanner) (grub_realloc((ptr), (size))) /* * As we don't have access to yyscanner, we cannot do much except to @@ -68,9 +68,6 @@ static int grub_lexer_unput (const char *input, yyscan_t yyscanner); static int grub_lexer_resplit (const char *input, yyscan_t yyscanner); -static void grub_lexer_yyfree (void *, yyscan_t yyscanner); -static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner); -static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner); static void copy_string (struct grub_parser_param *, const char *, unsigned hint); @@ -339,25 +336,6 @@ yywrap (yyscan_t yyscanner) return grub_script_lexer_yywrap (yyget_extra (yyscanner), 0); } -static void -grub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused))) -{ - grub_free(ptr); -} - -static void* -grub_lexer_yyalloc (yy_size_t size, yyscan_t yyscanner __attribute__ ((unused))) -{ - return grub_malloc (size); -} - -static void* -grub_lexer_yyrealloc (void *ptr, yy_size_t size, - yyscan_t yyscanner __attribute__ ((unused))) -{ - return grub_realloc (ptr, size); -} - static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint) { grub_size_t size; From 11a779322155c717c59be78b8938f85b26ed94ee Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Sat, 16 Nov 2013 15:56:09 +0000 Subject: [PATCH 11/55] arm: delete superflouous save of r8 in grub_uboot_syscall --- ChangeLog | 5 +++++ grub-core/kern/arm/uboot/startup.S | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7b5a8125b..7e09c4d12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-16 Leif Lindholm + + * grub-core/kern/arm/uboot/startup.S: delete superflouous save of r8 + in grub_uboot_syscall + 2013-11-16 Vladimir Serbinenko Decrease stack usage in lexer. diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/uboot/startup.S index df1e32928..3e1c1f2d6 100644 --- a/grub-core/kern/arm/uboot/startup.S +++ b/grub-core/kern/arm/uboot/startup.S @@ -137,7 +137,6 @@ FUNCTION(grub_uboot_syscall) mov lr, pc ldr pc, grub_uboot_syscall_ptr - str r8, gd_backup ldr r8, transition_space ldr lr, transition_space + 4 From 9ef81064a308cf60cf1e5d6ac8609fbd99636d0a Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 17:37:06 +0100 Subject: [PATCH 12/55] * grub-core/kern/arm/cache.S: Don't switch back to ARM mode when compiling to thumb2. * grub-core/kern/arm/cache_armv7.S: Likewise. * grub-core/lib/arm/setjmp.S: Likewise. --- ChangeLog | 7 +++++++ grub-core/kern/arm/cache.S | 5 +++++ grub-core/kern/arm/cache_armv7.S | 21 ++++++++++++++++----- grub-core/lib/arm/setjmp.S | 11 +++++++++-- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e09c4d12..9b0a85937 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-11-16 Vladimir Serbinenko + + * grub-core/kern/arm/cache.S: Don't switch back to ARM mode when + compiling to thumb2. + * grub-core/kern/arm/cache_armv7.S: Likewise. + * grub-core/lib/arm/setjmp.S: Likewise. + 2013-11-16 Leif Lindholm * grub-core/kern/arm/uboot/startup.S: delete superflouous save of r8 diff --git a/grub-core/kern/arm/cache.S b/grub-core/kern/arm/cache.S index 8522d2470..2ad774d90 100644 --- a/grub-core/kern/arm/cache.S +++ b/grub-core/kern/arm/cache.S @@ -21,7 +21,12 @@ .file "cache.S" .text .syntax unified +#if !defined (__thumb2__) || !defined (ARMV7) .arm +#else + .thumb +#endif + #if !defined (ARMV6) && !defined (ARMV7) # error Unsupported architecture version! #endif diff --git a/grub-core/kern/arm/cache_armv7.S b/grub-core/kern/arm/cache_armv7.S index 0c16b1047..aa42fad81 100644 --- a/grub-core/kern/arm/cache_armv7.S +++ b/grub-core/kern/arm/cache_armv7.S @@ -21,8 +21,13 @@ .file "cache_armv7.S" .text .syntax unified - .arm +#if !defined (__thumb2__) .arch armv7a + .arm +#else + .arch armv7 + .thumb +#endif # define DMB dmb # define DSB dsb # define ISB isb @@ -58,11 +63,17 @@ clean_invalidate_dcache: @ read current cache information mrc p15, 1, r8, c0, c0, 0 @ Read CCSIDR lsr r3, r8, #13 @ Number of sets -1 - ldr r9, =0x3fff - and r3, r3, r9 + + @ Keep only 14 bits of r3 + lsl r3, r3, #18 + lsr r3, r3, #18 + lsr r4, r8, #3 @ Number of ways -1 - ldr r9, =0x1ff - and r4, r4, r9 + + @ Keep only 9 bits of r4 + lsl r4, r4, #23 + lsr r4, r4, #23 + and r7, r8, #7 @ log2(line size in words) - 2 add r7, r7, #2 @ adjust mov r8, #1 diff --git a/grub-core/lib/arm/setjmp.S b/grub-core/lib/arm/setjmp.S index 4f1567946..a5373d3a9 100644 --- a/grub-core/lib/arm/setjmp.S +++ b/grub-core/lib/arm/setjmp.S @@ -24,7 +24,11 @@ GRUB_MOD_LICENSE "GPLv3+" .syntax unified +#if !defined (__thumb2__) .arm +#else + .thumb +#endif .text @@ -32,7 +36,8 @@ GRUB_MOD_LICENSE "GPLv3+" * int grub_setjmp (grub_jmp_buf env) */ FUNCTION(grub_setjmp) - stm r0, { r4-r11, sp, lr } + mov r12, sp + stm r0, { r4-r12, lr } mov r0, #0 bx lr @@ -40,7 +45,9 @@ FUNCTION(grub_setjmp) * int grub_longjmp (grub_jmp_buf env, int val) */ FUNCTION(grub_longjmp) - ldm r0, { r4-r11, sp, lr } + ldm r0, { r4-r12, lr } + mov sp, r12 movs r0, r1 + it eq moveq r0, #1 bx lr From cd46aa6cefabd7b0fcb15cd614577e1ab8c7a841 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 20:21:16 +0100 Subject: [PATCH 13/55] Rewrite grub-install, grub-mkrescue, grub-mkstandalone and grub-mknetdir the function of these files exceeds what can be sanely handled in shell in posix-comaptible way. Also writing it in C extends the functionality to non-UNIX-like OS and minimal environments. --- ChangeLog | 12 + Makefile.am | 22 + Makefile.util.def | 158 ++- configure.ac | 24 +- grub-core/Makefile.am | 7 + grub-core/kern/emu/hostdisk.c | 75 ++ grub-core/osdep/aros/config.c | 94 ++ grub-core/osdep/aros/hostdisk.c | 62 + grub-core/osdep/basic/compress.c | 21 + grub-core/osdep/basic/init.c | 9 +- grub-core/osdep/basic/no_platform.c | 46 + grub-core/osdep/basic/platform.c | 26 + grub-core/osdep/compress.c | 5 + grub-core/osdep/config.c | 7 + grub-core/osdep/linux/platform.c | 85 ++ grub-core/osdep/platform.c | 7 + grub-core/osdep/platform_unix.c | 3 + grub-core/osdep/unix/compress.c | 41 + grub-core/osdep/unix/config.c | 139 +++ grub-core/osdep/unix/exec.c | 45 + grub-core/osdep/unix/hostdisk.c | 46 + grub-core/osdep/unix/platform.c | 213 ++++ grub-core/osdep/windows/config.c | 57 + grub-core/osdep/windows/hostdisk.c | 111 ++ grub-core/osdep/windows/init.c | 51 +- include/grub/emu/config.h | 48 + include/grub/emu/getroot.h | 12 + include/grub/emu/hostfile.h | 13 + include/grub/osdep/exec_unix.h | 39 + include/grub/osdep/hostfile_aros.h | 10 +- include/grub/osdep/hostfile_unix.h | 6 + include/grub/osdep/hostfile_windows.h | 3 + include/grub/util/install.h | 149 +++ po/Makefile.in.in | 4 +- po/Rules-windowsdir | 11 + tests/util/grub-shell.in | 6 +- util/config.c | 112 ++ util/grub-install-common.c | 863 ++++++++++++++ util/grub-install.c | 1539 +++++++++++++++++++++++++ util/grub-install.in | 829 ------------- util/grub-install_header | 263 ----- util/grub-mkimage.c | 13 +- util/grub-mknetdir.c | 212 ++++ util/grub-mknetdir.in | 183 --- util/grub-mkrescue.c | 827 +++++++++++++ util/grub-mkrescue.in | 493 -------- util/grub-mkstandalone.c | 372 ++++++ util/grub-mkstandalone.in | 130 --- util/grub-probe.c | 175 +-- util/misc.c | 14 +- util/mkimage.c | 48 +- util/probe.c | 172 +++ 52 files changed, 5811 insertions(+), 2101 deletions(-) create mode 100644 grub-core/osdep/aros/config.c create mode 100644 grub-core/osdep/basic/compress.c create mode 100644 grub-core/osdep/basic/no_platform.c create mode 100644 grub-core/osdep/basic/platform.c create mode 100644 grub-core/osdep/compress.c create mode 100644 grub-core/osdep/config.c create mode 100644 grub-core/osdep/linux/platform.c create mode 100644 grub-core/osdep/platform.c create mode 100644 grub-core/osdep/platform_unix.c create mode 100644 grub-core/osdep/unix/compress.c create mode 100644 grub-core/osdep/unix/config.c create mode 100644 grub-core/osdep/unix/platform.c create mode 100644 grub-core/osdep/windows/config.c create mode 100644 include/grub/emu/config.h create mode 100644 include/grub/osdep/exec_unix.h create mode 100644 po/Rules-windowsdir create mode 100644 util/config.c create mode 100644 util/grub-install-common.c create mode 100644 util/grub-install.c delete mode 100644 util/grub-install.in delete mode 100644 util/grub-install_header create mode 100644 util/grub-mknetdir.c delete mode 100644 util/grub-mknetdir.in create mode 100644 util/grub-mkrescue.c delete mode 100644 util/grub-mkrescue.in create mode 100644 util/grub-mkstandalone.c delete mode 100644 util/grub-mkstandalone.in create mode 100644 util/probe.c diff --git a/ChangeLog b/ChangeLog index 9b0a85937..46be8e6d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2013-11-16 Andrey Borzenkov + + * util/grub-install.c (device_map_check_duplicates): Fix incorrect + order of qsort arguments (number of elements vs. element size). + +2013-11-16 Vladimir Serbinenko + + Rewrite grub-install, grub-mkrescue, grub-mkstandalone and grub-mknetdir + the function of these files exceeds what can be sanely handled in shell + in posix-comaptible way. Also writing it in C extends the functionality + to non-UNIX-like OS and minimal environments. + 2013-11-16 Vladimir Serbinenko * grub-core/kern/arm/cache.S: Don't switch back to ARM mode when diff --git a/Makefile.am b/Makefile.am index 03ef96491..114c20045 100644 --- a/Makefile.am +++ b/Makefile.am @@ -397,5 +397,27 @@ default_payload.elf: grub-mkstandalone grub-mkimage pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump setpci lsacpi chain' --fonts= --themes= --locales= -d grub-core/ endif +windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows +windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA) + test -d $(windowsdir) && rm -rf $(windowsdir) || true + test -d $(windowsdir) || mkdir $(windowsdir) + $(MAKE) -C po $(AM_MAKEFLAGS) windowsdir + $(MAKE) -C grub-core $(AM_MAKEFLAGS) windowsdir + test -d $(windowsdir)/themes || mkdir $(windowsdir)/themes + test -d $(windowsdir)/themes/starfield || mkdir $(windowsdir)/themes/starfield + for x in $(PROGRAMS); do \ + $(STRIP) $$x -o $(windowsdir)/$$x; \ + done + for x in $(pkgdata_DATA); do \ + cp -fp $$x $(windowsdir)/$$x; \ + done + for x in $(starfield_DATA); do \ + cp -fp $$x $(windowsdir)/themes/starfield/$$(basename $$x); \ + done + +windowszip=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows.zip +windowszip: windowsdir + test -f $(windowszip) && rm $(windowszip) || true + zip -r $(windowszip) $(windowsdir) EXTRA_DIST += linguas.sh diff --git a/Makefile.util.def b/Makefile.util.def index f2a305fd3..ede74687e 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -171,6 +171,10 @@ program = { common = util/resolve.c; common = grub-core/kern/emu/argp_common.c; common = grub-core/osdep/init.c; + common = grub-core/osdep/config.c; + extra_dist = grub-core/osdep/windows/config.c; + extra_dist = grub-core/osdep/unix/config.c; + common = util/config.c; common = grub-core/kern/arm/dl_helper.c; @@ -310,6 +314,7 @@ program = { installdir = sbin; mansection = 8; common = util/grub-probe.c; + common = util/probe.c; common = grub-core/osdep/ofpath.c; common = grub-core/kern/emu/argp_common.c; common = grub-core/osdep/init.c; @@ -479,38 +484,165 @@ script = { installdir = grubconf; }; -script = { +program = { mansection = 1; name = grub-mkrescue; - common = util/grub-install_header; - common = util/grub-mkrescue.in; - enable = noemu; + + common = util/grub-mkrescue.c; + common = util/render-label.c; + common = util/glue-efi.c; + common = util/mkimage.c; + common = util/grub-install-common.c; + common = util/setup_bios.c; + common = util/setup_sparc.c; + common = grub-core/lib/reed_solomon.c; + common = grub-core/osdep/random.c; + common = grub-core/osdep/ofpath.c; + common = grub-core/osdep/platform.c; + common = grub-core/osdep/platform_unix.c; + common = grub-core/osdep/compress.c; + extra_dist = grub-core/osdep/unix/compress.c; + extra_dist = grub-core/osdep/basic/compress.c; + common = util/editenv.c; + common = grub-core/osdep/blocklist.c; + common = grub-core/osdep/config.c; + common = util/config.c; + + common = grub-core/kern/emu/hostfs.c; + common = grub-core/disk/host.c; + + common = grub-core/kern/arm/dl_helper.c; + + common = util/resolve.c; + + common = grub-core/kern/emu/argp_common.c; + common = grub-core/osdep/init.c; + + ldadd = '$(LIBLZMA)'; + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + + condition = COND_HAVE_EXEC; }; -script = { +program = { mansection = 1; name = grub-mkstandalone; - common = util/grub-install_header; - common = util/grub-mkstandalone.in; + common = util/grub-mkstandalone.c; + + common = util/render-label.c; + common = util/glue-efi.c; + common = util/mkimage.c; + common = util/grub-install-common.c; + common = util/setup_bios.c; + common = util/setup_sparc.c; + common = grub-core/lib/reed_solomon.c; + common = grub-core/osdep/random.c; + common = grub-core/osdep/ofpath.c; + common = grub-core/osdep/platform.c; + common = grub-core/osdep/platform_unix.c; + extra_dist = grub-core/osdep/linux/platform.c; + extra_dist = grub-core/osdep/basic/platform.c; + extra_dist = grub-core/osdep/basic/no_platform.c; + extra_dist = grub-core/osdep/unix/platform.c; + common = grub-core/osdep/compress.c; + common = util/editenv.c; + common = grub-core/osdep/blocklist.c; + common = grub-core/osdep/config.c; + common = util/config.c; + + common = grub-core/kern/emu/hostfs.c; + common = grub-core/disk/host.c; + + common = grub-core/kern/arm/dl_helper.c; + + common = util/resolve.c; + + common = grub-core/kern/emu/argp_common.c; + common = grub-core/osdep/init.c; + + ldadd = '$(LIBLZMA)'; + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; -script = { +program = { mansection = 8; installdir = sbin; name = grub-install; - common = util/grub-install_header; - common = util/grub-install.in; + common = util/grub-install.c; + common = util/probe.c; + common = util/mkimage.c; + common = util/grub-install-common.c; + common = util/setup_bios.c; + common = util/setup_sparc.c; + common = grub-core/lib/reed_solomon.c; + common = grub-core/osdep/random.c; + common = grub-core/osdep/ofpath.c; + common = grub-core/osdep/platform.c; + common = grub-core/osdep/platform_unix.c; + common = grub-core/osdep/compress.c; + common = util/editenv.c; + common = grub-core/osdep/blocklist.c; + common = grub-core/osdep/config.c; + common = util/config.c; + + common = grub-core/kern/arm/dl_helper.c; + + common = util/resolve.c; enable = noemu; + common = grub-core/kern/emu/argp_common.c; + common = grub-core/osdep/init.c; + + ldadd = '$(LIBLZMA)'; + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; -script = { +program = { mansection = 1; installdir = bin; name = grub-mknetdir; - common = util/grub-install_header; - common = util/grub-mknetdir.in; + common = util/grub-mknetdir.c; + + common = util/mkimage.c; + common = util/grub-install-common.c; + common = util/setup_bios.c; + common = util/setup_sparc.c; + common = grub-core/lib/reed_solomon.c; + common = grub-core/osdep/random.c; + common = grub-core/osdep/ofpath.c; + common = grub-core/osdep/platform.c; + common = grub-core/osdep/platform_unix.c; + common = grub-core/osdep/compress.c; + common = util/editenv.c; + common = grub-core/osdep/blocklist.c; + common = grub-core/osdep/config.c; + common = util/config.c; + + common = grub-core/kern/arm/dl_helper.c; + + common = util/resolve.c; + common = grub-core/kern/emu/argp_common.c; + common = grub-core/osdep/init.c; + + ldadd = '$(LIBLZMA)'; + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; script = { diff --git a/configure.ac b/configure.ac index 18429103b..9f8fb8a35 100644 --- a/configure.ac +++ b/configure.ac @@ -75,14 +75,10 @@ if test "x$TARGET_CFLAGS" = x; then TARGET_CFLAGS="$TARGET_CFLAGS -Os" fi -BUILD_CPPFLAGS="$BUILD_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\"" - # Default HOST_CPPFLAGS HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W" HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1" -HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_LIBDIR=\\\"\$(pkglibdir)\\\"" -HOST_CPPFLAGS="$HOST_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\"" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" @@ -192,6 +188,12 @@ case "$host_os" in cygwin | windows* | mingw32*) host_kernel=windows ;; esac +case "$host_os" in + cygwin | windows* | mingw32*) have_exec=n ;; + aros*) have_exec=n ;; + *) have_exec=y;; +esac + case "$platform" in coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;; multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;; @@ -1458,6 +1460,20 @@ AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes]) AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) AM_CONDITIONAL([COND_CYGWIN], [test x$target_os = xcygwin]) AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x]) +AM_CONDITIONAL([COND_HAVE_EXEC], [test "x$have_exec" = xy]) + +test "x$prefix" = xNONE && prefix="$ac_default_prefix" +test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" +datarootdir="$(eval echo "$datarootdir")" +grub_libdir="$(eval echo "$libdir")" +grub_localedir="$(eval echo "$localedir")" +grub_datadir="$(eval echo "$datadir")" +grub_sysconfdir="$(eval echo "$sysconfdir")" +AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir]) +AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir]) +AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir]) +AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir]) + # Output files. cpudir="${target_cpu}" diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 025bbded3..151b9339a 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -428,3 +428,10 @@ efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF) platform_DATA += efiemu32.o efiemu64.o CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o endif + +windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows +windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA) + test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform) + for x in $(platform_DATA); do \ + cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \ + done diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index e00c8fbed..08ae65478 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -609,3 +609,78 @@ grub_util_biosdisk_get_osdev (grub_disk_t disk) return map[disk->id].device; } + + +static char * +grub_util_path_concat_real (size_t n, int ext, va_list ap) +{ + size_t totlen = 0; + char **l = xmalloc ((n + ext) * sizeof (l[0])); + char *r, *p, *pi; + size_t i; + int first = 1; + + for (i = 0; i < n + ext; i++) + { + l[i] = va_arg (ap, char *); + if (l[i]) + totlen += strlen (l[i]) + 1; + } + + r = xmalloc (totlen + 10); + + p = r; + for (i = 0; i < n; i++) + { + pi = l[i]; + if (!pi) + continue; + while (*pi == '/') + pi++; + if ((p != r || (pi != l[i] && first)) && (p == r || *(p - 1) != '/')) + *p++ = '/'; + first = 0; + p = grub_stpcpy (p, pi); + while (p != r && p != r + 1 && *(p - 1) == '/') + p--; + } + + if (ext && l[i]) + p = grub_stpcpy (p, l[i]); + + *p = '\0'; + + free (l); + + return r; +} + +char * +grub_util_path_concat (size_t n, ...) +{ + va_list ap; + char *r; + + va_start (ap, n); + + r = grub_util_path_concat_real (n, 0, ap); + + va_end (ap); + + return r; +} + +char * +grub_util_path_concat_ext (size_t n, ...) +{ + va_list ap; + char *r; + + va_start (ap, n); + + r = grub_util_path_concat_real (n, 1, ap); + + va_end (ap); + + return r; +} diff --git a/grub-core/osdep/aros/config.c b/grub-core/osdep/aros/config.c new file mode 100644 index 000000000..99f3009e2 --- /dev/null +++ b/grub-core/osdep/aros/config.c @@ -0,0 +1,94 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 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 + +const char * +grub_util_get_config_filename (void) +{ + static char *value = NULL; + if (!value) + value = grub_util_path_concat (3, GRUB_SYSCONFDIR, + "default", "grub"); + return value; +} + +const char * +grub_util_get_pkgdatadir (void) +{ + const char *ret = getenv ("pkgdatadir"); + if (ret) + return ret; + return GRUB_DATADIR "/" PACKAGE; +} + +const char * +grub_util_get_pkglibdir (void) +{ + return GRUB_LIBDIR "/" PACKAGE; +} + +const char * +grub_util_get_localedir (void) +{ + return LOCALEDIR; +} + +void +grub_util_load_config (struct grub_util_config *cfg) +{ + const char *cfgfile; + FILE *f = NULL; + const char *v; + + memset (cfg, 0, sizeof (*cfg)); + + v = getenv ("GRUB_ENABLE_CRYPTODISK"); + if (v && v[0] == 'y' && v[1] == '\0') + cfg->is_cryptodisk_enabled = 1; + + v = getenv ("GRUB_DISTRIBUTOR"); + if (v) + cfg->grub_distributor = xstrdup (v); + + cfgfile = grub_util_get_config_filename (); + if (!grub_util_is_regular (cfgfile)) + return; + + f = grub_util_fopen (cfgfile, "r"); + if (f) + { + grub_util_parse_config (f, cfg, 0); + fclose (f); + } + else + grub_util_warn (_("cannot open config file `%s': %s"), + cfgfile, strerror (errno)); +} diff --git a/grub-core/osdep/aros/hostdisk.c b/grub-core/osdep/aros/hostdisk.c index 3fe442cf5..9c0a6c895 100644 --- a/grub-core/osdep/aros/hostdisk.c +++ b/grub-core/osdep/aros/hostdisk.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -516,6 +517,17 @@ grub_util_is_directory (const char *path) return S_ISDIR (st.st_mode); } +int +grub_util_is_regular (const char *path) +{ + struct stat st; + + if (stat (path, &st) == -1) + return 0; + + return S_ISREG (st.st_mode); +} + int grub_util_is_special_file (const char *path) { @@ -525,3 +537,53 @@ grub_util_is_special_file (const char *path) return 1; return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); } + +static char * +get_temp_name (void) +{ + static int ctr = 0; + char *t; + struct stat st; + + while (1) + { + t = xasprintf ("T:grub.%d.%d.%d.%d", (int) getpid (), (int) getppid (), + ctr++, time (0)); + if (stat (t, &st) == -1) + return t; + free (t); + } +} + +char * +grub_util_make_temporary_file (void) +{ + char *ret = get_temp_name (); + FILE *f; + + f = grub_util_fopen (ret, "wb"); + if (f) + fclose (f); + return ret; +} + +char * +grub_util_make_temporary_dir (void) +{ + char *ret = get_temp_name (); + + grub_util_mkdir (ret); + + return ret; +} + +grub_uint32_t +grub_util_get_mtime (const char *path) +{ + struct stat st; + + if (stat (path, &st) == -1) + return 0; + + return st.st_mtime; +} diff --git a/grub-core/osdep/basic/compress.c b/grub-core/osdep/basic/compress.c new file mode 100644 index 000000000..463ce4242 --- /dev/null +++ b/grub-core/osdep/basic/compress.c @@ -0,0 +1,21 @@ +#include +#include +#include + +int +grub_install_compress_gzip (const char *src, const char *dest) +{ + grub_util_error ("no compression is available for your platform"); +} + +int +grub_install_compress_xz (const char *src, const char *dest) +{ + grub_util_error ("no compression is available for your platform"); +} + +int +grub_install_compress_lzop (const char *src, const char *dest) +{ + grub_util_error ("no compression is available for your platform"); +} diff --git a/grub-core/osdep/basic/init.c b/grub-core/osdep/basic/init.c index f4a673b64..c54c710db 100644 --- a/grub-core/osdep/basic/init.c +++ b/grub-core/osdep/basic/init.c @@ -20,6 +20,7 @@ #include #include +#include #include "progname.h" @@ -29,7 +30,9 @@ grub_util_host_init (int *argc __attribute__ ((unused)), { set_program_name ((*argv)[0]); -#ifdef GRUB_UTIL - grub_util_init_nls (); -#endif +#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c new file mode 100644 index 000000000..32be5e8e3 --- /dev/null +++ b/grub-core/osdep/basic/no_platform.c @@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 "platform.c" + +void +grub_install_register_ieee1275 (int is_prep, const char *install_device, + int partno, const char *relpath) +{ + grub_util_error ("%s", "no IEEE1275 routines are available for your platform"); +} + +void +grub_install_register_efi (const char *efidir_disk, int efidir_part, + const char *efifile_path, + const char *efi_distributor) +{ + grub_util_error ("%s", "no EFI routines are available for your platform"); +} + +void +grub_install_sgi_setup (const char *install_device, + const char *imgfile, const char *destname) +{ + grub_util_error ("%s", "no SGI routines are available for your platform"); +} diff --git a/grub-core/osdep/basic/platform.c b/grub-core/osdep/basic/platform.c new file mode 100644 index 000000000..4b5502aeb --- /dev/null +++ b/grub-core/osdep/basic/platform.c @@ -0,0 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 + +const char * +grub_install_get_default_x86_platform (void) +{ + return "i386-pc"; +} + diff --git a/grub-core/osdep/compress.c b/grub-core/osdep/compress.c new file mode 100644 index 000000000..cc808d029 --- /dev/null +++ b/grub-core/osdep/compress.c @@ -0,0 +1,5 @@ +#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__) +#include "unix/compress.c" +#else +#include "basic/compress.c" +#endif diff --git a/grub-core/osdep/config.c b/grub-core/osdep/config.c new file mode 100644 index 000000000..b9f781972 --- /dev/null +++ b/grub-core/osdep/config.c @@ -0,0 +1,7 @@ +#if defined (__MINGW32__) && !defined (__CYGWIN__) +#include "windows/config.c" +#elif defined (__AROS__) +#include "aros/config.c" +#else +#include "unix/config.c" +#endif diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c new file mode 100644 index 000000000..ec67aad35 --- /dev/null +++ b/grub-core/osdep/linux/platform.c @@ -0,0 +1,85 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 + +static int +is_not_empty_directory (const char *dir) +{ + DIR *d; + struct dirent *de; + + d = opendir (dir); + if (!d) + return 0; + while ((de = readdir (d))) + { + if (strcmp (de->d_name, ".") == 0 + || strcmp (de->d_name, "..") == 0) + continue; + closedir (d); + return 1; + } + + closedir (d); + return 0; +} + +static int +is_64_kernel (void) +{ + struct utsname un; + + if (uname (&un) < 0) + return 0; + + return strcmp (un.machine, "x86_64") == 0; +} + +const char * +grub_install_get_default_x86_platform (void) +{ + /* + On Linux, we need the efivars kernel modules. + If no EFI is available this module just does nothing + besides a small hello and if we detect efi we'll load it + anyway later. So it should be safe to + try to load it here. + */ + grub_util_exec ((const char * []){ "modprobe", "-q", + "efivars", NULL }); + if (is_not_empty_directory ("/sys/firmware/efi")) + { + if (is_64_kernel ()) + return "x86_64-efi"; + else + return "i386-efi"; + } + else if (is_not_empty_directory ("/proc/device-tree")) + return "i386-ieee1275"; + else + return "i386-pc"; +} diff --git a/grub-core/osdep/platform.c b/grub-core/osdep/platform.c new file mode 100644 index 000000000..f7202642f --- /dev/null +++ b/grub-core/osdep/platform.c @@ -0,0 +1,7 @@ +#ifdef __linux__ +#include "linux/platform.c" +#elif defined (__MINGW32__) || defined (__CYGWIN__) || defined (__AROS__) +#include "basic/no_platform.c" +#else +#include "basic/platform.c" +#endif diff --git a/grub-core/osdep/platform_unix.c b/grub-core/osdep/platform_unix.c new file mode 100644 index 000000000..db6a02dd1 --- /dev/null +++ b/grub-core/osdep/platform_unix.c @@ -0,0 +1,3 @@ +#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__) +#include "unix/platform.c" +#endif diff --git a/grub-core/osdep/unix/compress.c b/grub-core/osdep/unix/compress.c new file mode 100644 index 000000000..dee56207f --- /dev/null +++ b/grub-core/osdep/unix/compress.c @@ -0,0 +1,41 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 +grub_install_compress_gzip (const char *src, const char *dest) +{ + return grub_util_exec_redirect ((const char * []) { "gzip", "--best", + "--stdout", NULL }, src, dest); +} + +int +grub_install_compress_xz (const char *src, const char *dest) +{ + return grub_util_exec_redirect ((const char * []) { "xz", + "--lzma2=dict=128KiB", "--check=none", "--stdout", NULL }, src, dest); +} + +int +grub_install_compress_lzop (const char *src, const char *dest) +{ + return grub_util_exec_redirect ((const char * []) { "lzop", "-9", "-c", + NULL }, src, dest); +} diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c new file mode 100644 index 000000000..c093e91ad --- /dev/null +++ b/grub-core/osdep/unix/config.c @@ -0,0 +1,139 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 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 + +const char * +grub_util_get_config_filename (void) +{ + static char *value = NULL; + if (!value) + value = grub_util_path_concat (3, GRUB_SYSCONFDIR, + "default", "grub"); + return value; +} + +const char * +grub_util_get_pkgdatadir (void) +{ + const char *ret = getenv ("pkgdatadir"); + if (ret) + return ret; + return GRUB_DATADIR "/" PACKAGE; +} + +const char * +grub_util_get_pkglibdir (void) +{ + return GRUB_LIBDIR "/" PACKAGE; +} + +const char * +grub_util_get_localedir (void) +{ + return LOCALEDIR; +} + +void +grub_util_load_config (struct grub_util_config *cfg) +{ + pid_t pid; + const char *argv[4]; + char *script, *ptr; + const char *cfgfile, *iptr; + FILE *f = NULL; + int fd; + const char *v; + + memset (cfg, 0, sizeof (*cfg)); + + v = getenv ("GRUB_ENABLE_CRYPTODISK"); + if (v && v[0] == 'y' && v[1] == '\0') + cfg->is_cryptodisk_enabled = 1; + + v = getenv ("GRUB_DISTRIBUTOR"); + if (v) + cfg->grub_distributor = xstrdup (v); + + cfgfile = grub_util_get_config_filename (); + if (!grub_util_is_regular (cfgfile)) + return; + + argv[0] = "sh"; + argv[1] = "-c"; + + script = xmalloc (4 * strlen (cfgfile) + 300); + + ptr = script; + memcpy (ptr, ". '", 3); + ptr += 3; + for (iptr = cfgfile; *iptr; iptr++) + { + if (*iptr == '\\') + { + memcpy (ptr, "'\\''", 4); + ptr += 4; + continue; + } + *ptr++ = *iptr; + } + + strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\", " + "\"$GRUB_ENABLE_CRYPTODISK\", \"$GRUB_DISTRIBUTOR\""); + + argv[2] = script; + argv[3] = '\0'; + + pid = grub_util_exec_pipe (argv, &fd); + if (pid) + f = fdopen (fd, "r"); + if (f) + { + grub_util_parse_config (f, cfg, 1); + fclose (f); + } + if (pid) + { + close (fd); + waitpid (pid, NULL, 0); + } + if (f) + return; + + f = grub_util_fopen (cfgfile, "r"); + if (f) + { + grub_util_parse_config (f, cfg, 0); + fclose (f); + } + else + grub_util_warn (_("cannot open config file `%s': %s"), + cfgfile, strerror (errno)); +} diff --git a/grub-core/osdep/unix/exec.c b/grub-core/osdep/unix/exec.c index 239a68b32..9a50e5b9f 100644 --- a/grub-core/osdep/unix/exec.c +++ b/grub-core/osdep/unix/exec.c @@ -38,6 +38,23 @@ grub_util_exec (const char *const *argv) { pid_t pid; int status = -1; + char *str, *pstr; + const char *const *ptr; + grub_size_t strl = 0; + for (ptr = argv; *ptr; ptr++) + strl += grub_strlen (*ptr) + 1; + pstr = str = xmalloc (strl); + for (ptr = argv; *ptr; ptr++) + { + pstr = grub_stpcpy (pstr, *ptr); + *pstr++ = ' '; + } + if (pstr > str) + pstr--; + *pstr = '\0'; + + grub_util_info ("executing %s", str); + grub_free (str); pid = fork (); if (pid < 0) @@ -71,6 +88,29 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file, { pid_t mdadm_pid; int status = -1; + char *str, *pstr; + const char *const *ptr; + grub_size_t strl = 0; + for (ptr = argv; *ptr; ptr++) + strl += grub_strlen (*ptr) + 1; + strl += grub_strlen (stdin_file) + 2; + strl += grub_strlen (stdout_file) + 2; + + pstr = str = xmalloc (strl); + for (ptr = argv; *ptr; ptr++) + { + pstr = grub_stpcpy (pstr, *ptr); + *pstr++ = ' '; + } + *pstr++ = '<'; + pstr = grub_stpcpy (pstr, stdin_file); + *pstr++ = ' '; + *pstr++ = '>'; + pstr = grub_stpcpy (pstr, stdout_file); + *pstr = '\0'; + + grub_util_info ("executing %s", str); + grub_free (str); mdadm_pid = fork (); if (mdadm_pid < 0) @@ -87,6 +127,8 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file, #endif in = open (stdin_file, O_RDONLY); + if (in < 0) + exit (127); dup2 (in, STDIN_FILENO); close (in); @@ -94,6 +136,9 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file, dup2 (out, STDOUT_FILENO); close (out); + if (out < 0) + exit (127); + /* Ensure child is not localised. */ setenv ("LC_ALL", "C", 1); diff --git a/grub-core/osdep/unix/hostdisk.c b/grub-core/osdep/unix/hostdisk.c index fe87855e2..1ca1abbfb 100644 --- a/grub-core/osdep/unix/hostdisk.c +++ b/grub-core/osdep/unix/hostdisk.c @@ -246,6 +246,17 @@ grub_util_is_regular (const char *path) return S_ISREG (st.st_mode); } +grub_uint32_t +grub_util_get_mtime (const char *path) +{ + struct stat st; + + if (stat (path, &st) == -1) + return 0; + + return st.st_mtime; +} + int grub_util_is_special_file (const char *path) { @@ -256,4 +267,39 @@ grub_util_is_special_file (const char *path) return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); } + +char * +grub_util_make_temporary_file (void) +{ + const char *t = getenv ("TMPDIR"); + size_t tl; + char *tmp; + if (!t) + t = "/tmp"; + tl = strlen (t); + tmp = xmalloc (tl + sizeof ("/grub.XXXXXX")); + memcpy (tmp, t, tl); + memcpy (tmp + tl, "/grub.XXXXXX", + sizeof ("/grub.XXXXXX")); + mkstemp (tmp); + return tmp; +} + +char * +grub_util_make_temporary_dir (void) +{ + const char *t = getenv ("TMPDIR"); + size_t tl; + char *tmp; + if (!t) + t = "/tmp"; + tl = strlen (t); + tmp = xmalloc (tl + sizeof ("/grub.XXXXXX")); + memcpy (tmp, t, tl); + memcpy (tmp + tl, "/grub.XXXXXX", + sizeof ("/grub.XXXXXX")); + mkdtemp (tmp); + return tmp; +} + #endif diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c new file mode 100644 index 000000000..65c93f150 --- /dev/null +++ b/grub-core/osdep/unix/platform.c @@ -0,0 +1,213 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 + +static char * +get_ofpathname (const char *dev) +{ + char *ret = xmalloc (2 * PATH_MAX); + char *end = ret + 2 * PATH_MAX - 1; + int fd; + pid_t pid; + char *ptr = ret; + + pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd); + if (!pid) + goto fail; + + FILE *fp = fdopen (fd, "r"); + if (!fp) + goto fail; + + while (!feof (fp) && ptr < end) + { + size_t r; + r = fread (ptr, 1, end - ptr, fp); + ptr += r; + } + + fclose (fp); + + return ret; + + fail: + grub_util_error (_("couldn't find IEEE1275 device tree path for %s.\nYou will have to set `boot-device' variable manually"), + dev); +} + +static void +grub_install_remove_efi_entries_by_distributor (const char *efi_distributor) +{ + int fd; + pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd); + char *line = NULL; + size_t len = 0; + + if (!pid) + { + grub_util_warn (_("Unable to open stream from %s: %s"), + "efibootmgr", strerror (errno)); + return; + } + + FILE *fp = fdopen (fd, "r"); + if (!fp) + { + grub_util_warn (_("Unable to open stream from %s: %s"), + "efibootmgr", strerror (errno)); + return; + } + + line = xmalloc (80); + len = 80; + while (1) + { + int ret; + char *bootnum; + ret = getline (&line, &len, fp); + if (ret == -1) + break; + if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) != 0 + || line[sizeof ("Boot") - 1] < '0' + || line[sizeof ("Boot") - 1] > '9') + continue; + if (!strcasestr (line, efi_distributor)) + continue; + bootnum = line + sizeof ("Boot") - 1; + bootnum[4] = '\0'; + if (!verbosity) + grub_util_exec ((const char * []){ "efibootmgr", "-q", + "-b", bootnum, "-B", NULL }); + else + grub_util_exec ((const char * []){ "efibootmgr", + "-b", bootnum, "-B", NULL }); + } + + free (line); +} + +void +grub_install_register_efi (const char *efidir_disk, int efidir_part, + const char *efifile_path, + const char *efi_distributor) +{ + if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL })) + { + /* TRANSLATORS: This message is shown when required executable `%s' + isn't found. */ + grub_util_error (_("%s: not found"), "efibootmgr"); + } + + /* On Linux, we need the efivars kernel modules. */ +#ifdef __linux__ + grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL }); +#endif + /* Delete old entries from the same distributor. */ + grub_install_remove_efi_entries_by_distributor (efi_distributor); + + char *efidir_part_str = xasprintf ("%d", efidir_part); + + if (!verbosity) + grub_util_exec ((const char * []){ "efibootmgr", "-q", + "-c", "-d", efidir_disk, + "-p", efidir_part_str, "-w", + "-L", efi_distributor, "-l", + efifile_path, NULL }); + else + grub_util_exec ((const char * []){ "efibootmgr", + "-c", "-d", efidir_disk, + "-p", efidir_part_str, "-w", + "-L", efi_distributor, "-l", + efifile_path, NULL }); + free (efidir_part_str); +} + +void +grub_install_register_ieee1275 (int is_prep, const char *install_device, + int partno, const char *relpath) +{ + char *boot_device; + + if (grub_util_exec_redirect_null ((const char * []){ "ofpathname", "--version", NULL })) + { + /* TRANSLATORS: This message is shown when required executable `%s' + isn't found. */ + grub_util_error (_("%s: not found"), "ofpathname"); + } + + /* Get the Open Firmware device tree path translation. */ + if (!is_prep) + { + char *ptr; + char *ofpath; + const char *iptr; + + ofpath = get_ofpathname (install_device); + boot_device = xmalloc (strlen (ofpath) + 1 + + sizeof ("XXXXXXXXXXXXXXXXXXXX") + + 1 + strlen (relpath) + 1); + ptr = grub_stpcpy (boot_device, ofpath); + *ptr++ = ':'; + grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXXX"), "%d", + partno); + ptr += strlen (ptr); + *ptr++ = ','; + for (iptr = relpath; *iptr; iptr++, ptr++) + { + if (*iptr == '/') + *ptr = '\\'; + else + *ptr = *iptr; + } + *ptr = '\0'; + } + else + boot_device = get_ofpathname (install_device); + + if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device", + boot_device, NULL })) + { + char *cmd = xasprintf ("setenv boot-device %s", boot_device); + grub_util_error ("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n", + cmd); + free (cmd); + } + + free (boot_device); +} + +void +grub_install_sgi_setup (const char *install_device, + const char *imgfile, const char *destname) +{ + grub_util_exec ((const char * []){ "dvhtool", "-d", + install_device, "--unix-to-vh", + imgfile, destname, NULL }); + grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually.")); +} diff --git a/grub-core/osdep/windows/config.c b/grub-core/osdep/windows/config.c new file mode 100644 index 000000000..823eac884 --- /dev/null +++ b/grub-core/osdep/windows/config.c @@ -0,0 +1,57 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 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 + +void +grub_util_load_config (struct grub_util_config *cfg) +{ + const char *cfgfile; + FILE *f = NULL; + const char *v; + + cfgfile = grub_util_get_config_filename (); + if (!grub_util_is_regular (cfgfile)) + return; + + memset (cfg, 0, sizeof (*cfg)); + + v = getenv ("GRUB_ENABLE_CRYPTODISK"); + if (v && v[0] == 'y' && v[1] == '\0') + cfg->is_cryptodisk_enabled = 1; + + v = getenv ("GRUB_DISTRIBUTOR"); + if (v) + cfg->grub_distributor = xstrdup (v); + + f = grub_util_fopen (cfgfile, "r"); + if (f) + { + grub_util_parse_config (f, cfg, 0); + fclose (f); + } + else + grub_util_warn (_("cannot open config file `%s': %s"), + cfgfile, strerror (errno)); +} diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c index f396c8700..6d7d12097 100644 --- a/grub-core/osdep/windows/hostdisk.c +++ b/grub-core/osdep/windows/hostdisk.c @@ -46,6 +46,7 @@ #include #include +#include #if SIZEOF_TCHAR == 1 @@ -411,6 +412,89 @@ grub_util_unlink (const char *name) return ret; } +int +grub_util_rmdir (const char *name) +{ + LPTSTR name_windows; + int ret; + + name_windows = grub_util_get_windows_path (name); + + ret = !RemoveDirectory (name_windows); + free (name_windows); + return ret; +} + +static char * +get_temp_name (void) +{ + TCHAR rt[1024]; + TCHAR *ptr; + HCRYPTPROV hCryptProv; + grub_uint8_t rnd[5]; + const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5; + int i; + + GetTempPath (ARRAY_SIZE (rt) - 100, rt); + + if (!CryptAcquireContext (&hCryptProv, + NULL, + MS_DEF_PROV, + PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT) + || !CryptGenRandom (hCryptProv, 5, rnd)) + grub_util_error ("%s", _("couldn't retrieve random data")); + + CryptReleaseContext (hCryptProv, 0); + + for (ptr = rt; *ptr; ptr++); + memcpy (ptr, TEXT("\\GRUB."), sizeof (TEXT("\\GRUB."))); + ptr += sizeof ("\\GRUB.") - 1; + + for (i = 0; i < 8; i++) + { + grub_size_t b = i * 5; + grub_uint8_t r; + grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT; + grub_size_t f2; + if (f1 > 5) + f1 = 5; + f2 = 5 - f1; + r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1); + if (f2) + r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1; + if (r < 10) + *ptr++ = '0' + r; + else + *ptr++ = 'a' + (r - 10); + } + *ptr = '\0'; + + return grub_util_tchar_to_utf8 (rt); +} + +char * +grub_util_make_temporary_file (void) +{ + char *ret = get_temp_name (); + FILE *f; + + f = grub_util_fopen (ret, "wb"); + if (f) + fclose (f); + return ret; +} + +char * +grub_util_make_temporary_dir (void) +{ + char *ret = get_temp_name (); + + grub_util_mkdir (ret); + + return ret; +} + int grub_util_is_directory (const char *name) { @@ -444,6 +528,33 @@ grub_util_is_regular (const char *name) && !(attr & FILE_ATTRIBUTE_REPARSE_POINT) && attr; } +grub_uint32_t +grub_util_get_mtime (const char *path) +{ + LPTSTR name_windows; + BOOL b; + WIN32_FILE_ATTRIBUTE_DATA attr; + ULARGE_INTEGER us_ul; + + name_windows = grub_util_get_windows_path (path); + if (!name_windows) + return 0; + + b = GetFileAttributesEx (name_windows, GetFileExInfoStandard, &attr); + grub_free (name_windows); + + if (!b) + return 0; + + us_ul.LowPart = attr.ftLastWriteTime.dwLowDateTime; + us_ul.HighPart = attr.ftLastWriteTime.dwHighDateTime; + + return (us_ul.QuadPart / 10000000) + - 86400ULL * 365 * (1970 - 1601) + - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); +} + + #ifdef __MINGW32__ FILE * diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c index 45554f1b2..98c325c20 100644 --- a/grub-core/osdep/windows/init.c +++ b/grub-core/osdep/windows/init.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -111,10 +112,42 @@ set_console_unicode_font (void) } } +static char *grub_util_base_directory; +static char *locale_dir; + +const char * +grub_util_get_config_filename (void) +{ + static char *value = NULL; + if (!value) + value = grub_util_path_concat (2, grub_util_base_directory, "grub.cfg"); + return value; +} + +const char * +grub_util_get_pkgdatadir (void) +{ + return grub_util_base_directory; +} + +const char * +grub_util_get_localedir (void) +{ + return locale_dir; +} + +const char * +grub_util_get_pkglibdir (void) +{ + return grub_util_base_directory; +} + void grub_util_host_init (int *argc __attribute__ ((unused)), char ***argv) { + char *ptr; + SetConsoleOutputCP (CP_UTF8); SetConsoleCP (CP_UTF8); @@ -137,9 +170,21 @@ grub_util_host_init (int *argc __attribute__ ((unused)), #error "Unsupported TCHAR size" #endif + grub_util_base_directory = canonicalize_file_name ((*argv)[0]); + if (!grub_util_base_directory) + grub_util_base_directory = xstrdup ((*argv)[0]); + for (ptr = grub_util_base_directory + strlen (grub_util_base_directory) - 1; + ptr >= grub_util_base_directory && *ptr != '/' && *ptr != '\\'; ptr--); + if (ptr >= grub_util_base_directory) + *ptr = '\0'; + + locale_dir = grub_util_path_concat (2, grub_util_base_directory, "locale"); + set_program_name ((*argv)[0]); -#ifdef GRUB_UTIL - grub_util_init_nls (); -#endif +#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, locale_dir); + textdomain (PACKAGE); +#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } diff --git a/include/grub/emu/config.h b/include/grub/emu/config.h new file mode 100644 index 000000000..875d5896c --- /dev/null +++ b/include/grub/emu/config.h @@ -0,0 +1,48 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 . + */ + +#ifndef GRUB_CONFIG_EMU_HEADER +#define GRUB_CONFIG_EMU_HEADER 1 + +#include +#include +#include +#include + +const char * +grub_util_get_config_filename (void); +const char * +grub_util_get_pkgdatadir (void); +const char * +grub_util_get_pkglibdir (void); +const char * +grub_util_get_localedir (void); + +struct grub_util_config +{ + int is_cryptodisk_enabled; + char *grub_distributor; +}; + +void +grub_util_load_config (struct grub_util_config *cfg); + +void +grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple); + +#endif diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h index 675cf78be..73fa2d34a 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h @@ -20,8 +20,10 @@ #define GRUB_UTIL_GETROOT_HEADER 1 #include +#include #include +#include enum grub_dev_abstraction_types { GRUB_DEV_ABSTRACTION_NONE, @@ -89,4 +91,14 @@ grub_util_get_grub_dev_os (const char *os_dev); grub_disk_addr_t grub_util_find_partition_start_os (const char *dev); +char * +grub_util_guess_bios_drive (const char *orig_path); +char * +grub_util_guess_efi_drive (const char *orig_path); +char * +grub_util_guess_baremetal_drive (const char *orig_path); +void +grub_util_fprint_full_disk_name (FILE *f, + const char *drive, grub_device_t dev); + #endif /* ! GRUB_UTIL_GETROOT_HEADER */ diff --git a/include/grub/emu/hostfile.h b/include/grub/emu/hostfile.h index 3ca1ab248..ab01fbce8 100644 --- a/include/grub/emu/hostfile.h +++ b/include/grub/emu/hostfile.h @@ -31,6 +31,11 @@ grub_util_is_special_file (const char *path); int grub_util_is_regular (const char *path); +char * +grub_util_path_concat (size_t n, ...); +char * +grub_util_path_concat_ext (size_t n, ...); + int grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off); ssize_t @@ -49,5 +54,13 @@ EXPORT_FUNC(grub_util_fd_close) (grub_util_fd_t fd); grub_uint64_t grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize); +char * +grub_util_make_temporary_file (void); +char * +grub_util_make_temporary_dir (void); +void +grub_util_unlink_recursive (const char *name); +grub_uint32_t +grub_util_get_mtime (const char *name); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/include/grub/osdep/exec_unix.h b/include/grub/osdep/exec_unix.h new file mode 100644 index 000000000..ecc3adc30 --- /dev/null +++ b/include/grub/osdep/exec_unix.h @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 . + */ + +#ifndef GRUB_EMU_EXEC_H +#define GRUB_EMU_EXEC_H 1 + +#include +#include + +#include +pid_t +grub_util_exec_pipe (const char *const *argv, int *fd); +pid_t +grub_util_exec_pipe_stderr (const char *const *argv, int *fd); + +int +grub_util_exec (const char *const *argv); +int +grub_util_exec_redirect (const char *const *argv, const char *stdin_file, + const char *stdout_file); +int +grub_util_exec_redirect_null (const char *const *argv); + +#endif diff --git a/include/grub/osdep/hostfile_aros.h b/include/grub/osdep/hostfile_aros.h index 3a5043587..4ec211b48 100644 --- a/include/grub/osdep/hostfile_aros.h +++ b/include/grub/osdep/hostfile_aros.h @@ -50,6 +50,12 @@ grub_util_fd_readdir (grub_util_fd_dir_t dirp) return readdir (dirp); } +static inline int +grub_util_rmdir (const char *pathname) +{ + return rmdir (pathname); +} + static inline int grub_util_unlink (const char *pathname) { @@ -62,7 +68,7 @@ grub_util_rename (const char *from, const char *to) return rename (from, to); } -#define grub_util_mkdir(a) mkdir (a) +#define grub_util_mkdir(a) mkdir (a, 0700) struct grub_util_fd { @@ -86,7 +92,7 @@ enum grub_util_fd_open_flags_t GRUB_UTIL_FD_O_RDONLY = O_RDONLY, GRUB_UTIL_FD_O_WRONLY = O_WRONLY, GRUB_UTIL_FD_O_RDWR = O_RDWR, - GRUB_UTIL_FD_O_CREAT = O_CREAT, + GRUB_UTIL_FD_O_CREATTRUNC = O_CREAT | O_TRUNC, GRUB_UTIL_FD_O_SYNC = (0 #ifdef O_SYNC | O_SYNC diff --git a/include/grub/osdep/hostfile_unix.h b/include/grub/osdep/hostfile_unix.h index 50883f44f..e4e89398c 100644 --- a/include/grub/osdep/hostfile_unix.h +++ b/include/grub/osdep/hostfile_unix.h @@ -59,6 +59,12 @@ grub_util_unlink (const char *pathname) return unlink (pathname); } +static inline int +grub_util_rmdir (const char *pathname) +{ + return rmdir (pathname); +} + static inline int grub_util_rename (const char *from, const char *to) { diff --git a/include/grub/osdep/hostfile_windows.h b/include/grub/osdep/hostfile_windows.h index ff21b6f93..e928b3f96 100644 --- a/include/grub/osdep/hostfile_windows.h +++ b/include/grub/osdep/hostfile_windows.h @@ -55,6 +55,9 @@ grub_util_fd_closedir (grub_util_fd_dir_t dirp); grub_util_fd_dirent_t grub_util_fd_readdir (grub_util_fd_dir_t dirp); +int +grub_util_rmdir (const char *pathname); + enum grub_util_fd_open_flags_t { GRUB_UTIL_FD_O_RDONLY = 1, diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 7eb6141a5..c1cd6b339 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -26,6 +26,104 @@ #include #include +#define GRUB_INSTALL_OPTIONS \ + { "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \ + 0, N_("pre-load specified modules MODULES"), 1 }, \ + { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \ + N_("MODULES"), 0, \ + N_("install only MODULES and their dependencies [default=all]"), 1 }, \ + { "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"), \ + 0, N_("install THEMES [default=%s]"), 1 }, \ + { "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"), \ + 0, N_("install FONTS [default=%s]"), 1 }, \ + { "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\ + 0, N_("install only LOCALES [default=all]"), 1 }, \ + { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \ + "no,xz,gz,lzo", OPTION_ARG_OPTIONAL, \ + N_("compress GRUB files [optional]"), 1 }, \ + /* TRANSLATORS: platform here isn't identifier. It can be translated. */ \ + { "directory", 'd', N_("DIR"), 0, \ + N_("use images and modules under DIR [default=%s/]"), 1 }, \ + { "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2, \ + N_("DIR"), OPTION_HIDDEN, \ + N_("use images and modules under DIR [default=%s/]"), 1 }, \ + { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \ + "FILE", OPTION_HIDDEN, 0, 1 }, \ + /* TRANSLATORS: "embed" is a verb (command description). "*/ \ + { "pubkey", 'k', N_("FILE"), 0, \ + N_("embed FILE as public key for signature checking"), 0}, \ + { "verbose", 'v', 0, 0, \ + N_("increase verbosity"), 1 } + +int +grub_install_parse (int key, char *arg); + +void +grub_install_push_module (const char *val); + +void +grub_install_pop_module (void); + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))); + +enum grub_install_plat + { + GRUB_INSTALL_PLATFORM_I386_PC, + GRUB_INSTALL_PLATFORM_I386_EFI, + GRUB_INSTALL_PLATFORM_I386_QEMU, + GRUB_INSTALL_PLATFORM_I386_COREBOOT, + GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, + GRUB_INSTALL_PLATFORM_I386_IEEE1275, + GRUB_INSTALL_PLATFORM_X86_64_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, + GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, + GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, + GRUB_INSTALL_PLATFORM_MIPSEL_ARC, + GRUB_INSTALL_PLATFORM_MIPS_ARC, + GRUB_INSTALL_PLATFORM_IA64_EFI, + GRUB_INSTALL_PLATFORM_ARM_UBOOT, + GRUB_INSTALL_PLATFORM_ARM_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_MAX + }; + +enum grub_install_options { + GRUB_INSTALL_OPTIONS_DIRECTORY = 'd', + GRUB_INSTALL_OPTIONS_VERBOSITY = 'v', + GRUB_INSTALL_OPTIONS_MODULES = 0x201, + GRUB_INSTALL_OPTIONS_INSTALL_MODULES, + GRUB_INSTALL_OPTIONS_INSTALL_THEMES, + GRUB_INSTALL_OPTIONS_INSTALL_FONTS, + GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, + GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, + GRUB_INSTALL_OPTIONS_DIRECTORY2, + GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE +}; + +extern char *grub_install_source_directory; + +enum grub_install_plat +grub_install_get_target (const char *src); +void +grub_install_mkdir_p (const char *dst); + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid); +char * +grub_install_get_platform_name (enum grub_install_plat platid); + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid); + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid); + + typedef enum { GRUB_COMPRESSION_AUTO, GRUB_COMPRESSION_NONE, @@ -33,6 +131,25 @@ typedef enum { GRUB_COMPRESSION_LZMA } grub_compression_t; +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *format, int note, + grub_compression_t comp); +void +grub_install_make_image_wrap_file (const char *dir, const char *prefix, + FILE *fp, const char *outname, + char *memdisk_path, + char *config_path, + const char *mkimage_target, int note, + grub_compression_t comp); + +int +grub_install_copy_file (const char *src, + const char *dst, + int is_critical); + struct grub_install_image_target_desc; void @@ -66,6 +183,32 @@ grub_install_get_image_targets_string (void); const char * grub_util_get_target_dirname (const struct grub_install_image_target_desc *t); +void +grub_install_create_envblk_file (const char *name); + +const char * +grub_install_get_default_x86_platform (void); + +void +grub_install_register_efi (const char *efidir_disk, int efidir_part, + const char *efifile_path, + const char *efi_distributor); + +void +grub_install_register_ieee1275 (int is_prep, const char *install_device, + int partno, const char *relpath); + +void +grub_install_sgi_setup (const char *install_device, + const char *imgfile, const char *destname); + +int +grub_install_compress_gzip (const char *src, const char *dest); +int +grub_install_compress_lzop (const char *src, const char *dest); +int +grub_install_compress_xz (const char *src, const char *dest); + void grub_install_get_blocklist (grub_device_t root_dev, const char *core_path, const char *core_img, @@ -89,4 +232,10 @@ grub_util_render_label (const char *label_font, const char *label_string, const char *label); +const char * +grub_util_get_target_name (const struct grub_install_image_target_desc *t); + +extern char *grub_install_copy_buffer; +#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576 + #endif diff --git a/po/Makefile.in.in b/po/Makefile.in.in index 83a3220d6..3619458e8 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -68,10 +68,10 @@ UPDATEPOFILES = @UPDATEPOFILES@ DUMMYPOFILES = @DUMMYPOFILES@ DISTFILES.common = Makefile.in.in remove-potcdate.sin \ $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) \ -$(DISTFILES.common.extra3) $(DISTFILES.common.extra4) +$(DISTFILES.common.extra3) $(DISTFILES.common.extra4) $(DISTFILES.common.extra5) DISTFILES = $(DISTFILES.common) Makevars POTFILES.in POTFILES-shell.in \ $(POFILES) $(GMOFILES) \ -$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) $(DISTFILES.extra4) grub.d.sed README +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) $(DISTFILES.extra4) $(DISTFILES.extra5) grub.d.sed README POTFILES = \ diff --git a/po/Rules-windowsdir b/po/Rules-windowsdir new file mode 100644 index 000000000..fe47b1060 --- /dev/null +++ b/po/Rules-windowsdir @@ -0,0 +1,11 @@ +# generate windowsdir + +DISTFILES.common.extra5 = Rules-windowsdir + +windowsdir="$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows" +windowsdir: $(GMOFILES) + test -d "$(windowsdir)/locale" || mkdir "$(windowsdir)/locale" + for x in $(CATALOGS); do \ + test -d "$(windowsdir)/locale/$${x%.gmo}" || mkdir "$(windowsdir)/locale/$${x%.gmo}"; \ + cp -fp "$(srcdir)/$$x" "$(windowsdir)/locale/$${x%.gmo}/grub.mo"; \ + done diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index fc435b68a..22277fbdf 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -347,8 +347,8 @@ fi if [ x$boot != xnet ] && [ x$boot != xemu ]; then cp -R "@srcdir@/themes" "@builddir@" - pkgdatadir="@builddir@" sh "@builddir@/grub-mkrescue" "--grub-mkimage=${builddir}/grub-mkimage" "--grub-render-label=${builddir}/grub-render-label" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ - --rom-directory="${rom_directory}" "--grub-mkimage-extra=$mkimage_extra_arg" ${mkrescue_args} \ + pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ + --rom-directory="${rom_directory}" $mkimage_extra_arg ${mkrescue_args} \ "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \ ${files} >/dev/null 2>&1 fi @@ -418,7 +418,7 @@ do_trim () if [ x$boot = xnet ]; then netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 - pkgdatadir="@builddir@" sh "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null + pkgdatadir="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null cp "${cfgfile}" "$netdir/boot/grub/grub.cfg" cp "${source}" "$netdir/boot/grub/testcase.cfg" timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim diff --git a/util/config.c b/util/config.c new file mode 100644 index 000000000..f313714db --- /dev/null +++ b/util/config.c @@ -0,0 +1,112 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 + +void +grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple) +{ + char *buffer = NULL; + size_t sz = 0; + while (getline (&buffer, &sz, f) >= 0) + { + const char *ptr; + for (ptr = buffer; *ptr && grub_isspace (*ptr); ptr++); + if (grub_strncmp (ptr, "GRUB_ENABLE_CRYPTODISK=", + sizeof ("GRUB_ENABLE_CRYPTODISK=") - 1) == 0) + { + ptr += sizeof ("GRUB_ENABLE_CRYPTODISK=") - 1; + if (*ptr == '"' || *ptr == '\'') + ptr++; + if (*ptr == 'y') + cfg->is_cryptodisk_enabled = 1; + continue; + } + if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=", + sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0) + { + char *optr; + enum { NONE, SNGLQUOT, DBLQUOT } state; + if (simple) + { + free (cfg->grub_distributor); + cfg->grub_distributor = xstrdup (ptr); + continue; + } + free (cfg->grub_distributor); + cfg->grub_distributor = xmalloc (strlen (ptr) + 1); + optr = cfg->grub_distributor; + state = NONE; + + for (; *ptr; ptr++) + switch (*ptr) + { + case '\\': + if (state == SNGLQUOT) + { + *optr++ = *ptr; + continue; + } + if (ptr[1]) + { + *optr++ = ptr[1]; + ptr++; + continue; + } + ptr++; + break; + case '"': + if (state == NONE) + { + state = DBLQUOT; + continue; + } + if (state == DBLQUOT) + { + state = NONE; + continue; + } + *optr++ = *ptr; + continue; + case '\'': + if (state == SNGLQUOT) + { + state = NONE; + continue; + } + if (state == NONE) + { + state = SNGLQUOT; + continue; + } + *optr++ = *ptr; + continue; + default: + *optr++ = *ptr; + continue; + } + *optr = '\0'; + } + } +} + diff --git a/util/grub-install-common.c b/util/grub-install-common.c new file mode 100644 index 000000000..75a315d06 --- /dev/null +++ b/util/grub-install-common.c @@ -0,0 +1,863 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 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 +#include + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))) +{ + switch (key) + { + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + return xasprintf(text, "starfield"); + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + return xasprintf(text, "unicode"); + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + return xasprintf(text, grub_util_get_pkglibdir ()); + default: + return (char *) text; + } +} + +static int (*compress_func) (const char *src, const char *dest) = NULL; +char *grub_install_copy_buffer; + +int +grub_install_copy_file (const char *src, + const char *dst, + int is_needed) +{ + grub_util_fd_t in, out; + ssize_t r; + + grub_util_info ("copying `%s' -> `%s'", src, dst); + + in = grub_util_fd_open (src, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (in)) + { + if (is_needed) + grub_util_error (_("cannot open `%s': %s"), src, grub_util_fd_strerror ()); + else + grub_util_info (_("cannot open `%s': %s"), src, grub_util_fd_strerror ()); + return 0; + } + out = grub_util_fd_open (dst, GRUB_UTIL_FD_O_WRONLY + | GRUB_UTIL_FD_O_CREATTRUNC); + if (!GRUB_UTIL_FD_IS_VALID (out)) + { + grub_util_error (_("cannot open `%s': %s"), dst, + grub_util_fd_strerror ()); + grub_util_fd_close (in); + return 0; + } + + if (!grub_install_copy_buffer) + grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE); + + while (1) + { + r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE); + if (r <= 0) + break; + grub_util_fd_write (out, grub_install_copy_buffer, r); + } + grub_util_fd_sync (out); + grub_util_fd_close (in); + grub_util_fd_close (out); + + if (r < 0) + grub_util_error ("cannot copy `%s' to `%s': %s", + src, dst, grub_util_fd_strerror ()); + + return 1; +} + +int +grub_install_compress_file (const char *in_name, + const char *out_name, + int is_needed) +{ + int ret; + + if (!compress_func) + ret = grub_install_copy_file (in_name, out_name, is_needed); + else + { + grub_util_info ("compressing `%s' -> `%s'", in_name, out_name); + ret = !compress_func (in_name, out_name); + if (!ret && is_needed) + grub_util_warn ("can't compress `%s' to `%s'", in_name, out_name); + } + + if (!ret && is_needed) + grub_util_error ("cannot copy `%s' to `%s': %s", + in_name, out_name, grub_util_fd_strerror ()); + + return ret; +} + +static int +is_path_separator (char c) +{ +#if defined (__MINGW32__) || defined (__CYGWIN__) + if (c == '\\') + return 1; +#endif + if (c == '/') + return 1; + return 0; +} + +void +grub_install_mkdir_p (const char *dst) +{ + char *t = xstrdup (dst); + char *p; + for (p = t; *p; p++) + { + if (is_path_separator (*p)) + { + char s = *p; + *p = '\0'; + grub_util_mkdir (t); + *p = s; + } + } + grub_util_mkdir (t); + free (t); +} + +static void +clean_grub_dir (const char *di) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (di); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + di, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + const char *ext = strrchr (de->d_name, '.'); + if ((ext && (strcmp (ext, ".mod") == 0 + || strcmp (ext, ".lst") == 0 + || strcmp (ext, ".img") == 0 + || strcmp (ext, ".mo") == 0) + && strcmp (de->d_name, "menu.lst") != 0) + || strcmp (de->d_name, "efiemu32.o") == 0 + || strcmp (de->d_name, "efiemu64.o") == 0) + { + char *x = grub_util_path_concat (2, di, de->d_name); + if (grub_util_unlink (x) < 0) + grub_util_error ("cannont delete `%s': %s", x, + grub_util_fd_strerror ()); + free (x); + } + } + grub_util_fd_closedir (d); +} + +struct install_list +{ + int is_default; + char **entries; + size_t n_entries; + size_t n_alloc; +}; + +struct install_list install_modules = { 1, 0, 0, 0 }; +struct install_list modules = { 1, 0, 0, 0 }; +struct install_list install_locales = { 1, 0, 0, 0 }; +struct install_list install_fonts = { 1, 0, 0, 0 }; +struct install_list install_themes = { 1, 0, 0, 0 }; +char *grub_install_source_directory = NULL; + +void +grub_install_push_module (const char *val) +{ + modules.is_default = 0; + if (modules.n_entries + 1 >= modules.n_alloc) + { + modules.n_alloc <<= 1; + if (modules.n_alloc < 16) + modules.n_alloc = 16; + modules.entries = xrealloc (modules.entries, + modules.n_alloc * sizeof (modules.entries)); + } + modules.entries[modules.n_entries++] = xstrdup (val); + modules.entries[modules.n_entries] = NULL; +} + +void +grub_install_pop_module (void) +{ + modules.n_entries--; + free (modules.entries[modules.n_entries]); + modules.entries[modules.n_entries] = NULL; +} + + +static void +handle_install_list (struct install_list *il, const char *val, + int default_all) +{ + const char *ptr; + char **ce; + il->is_default = 0; + free (il->entries); + il->entries = NULL; + il->n_entries = 0; + if (strcmp (val, "all") == 0 && default_all) + { + il->is_default = 1; + return; + } + ptr = val; + while (1) + { + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + il->n_entries++; + } + il->n_alloc = il->n_entries + 1; + il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); + for (ce = il->entries; ; ce++) + { + const char *bptr; + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + bptr = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + *ce = xmalloc (ptr - bptr + 1); + memcpy (*ce, bptr, ptr - bptr); + (*ce)[ptr - bptr] = '\0'; + ce++; + } + *ce = NULL; +} + +static char **pubkeys; +static size_t npubkeys; + +int +grub_install_parse (int key, char *arg) +{ + switch (key) + { + case 'k': + pubkeys = xrealloc (pubkeys, + sizeof (pubkeys[0]) + * (npubkeys + 1)); + pubkeys[npubkeys++] = xstrdup (arg); + return 1; + + case GRUB_INSTALL_OPTIONS_VERBOSITY: + verbosity++; + return 1; + + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + free (grub_install_source_directory); + grub_install_source_directory = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_MODULES: + handle_install_list (&install_modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_MODULES: + handle_install_list (&modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES: + handle_install_list (&install_locales, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + handle_install_list (&install_themes, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + handle_install_list (&install_fonts, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS: + if (strcmp (arg, "no") == 0) + { + compress_func = NULL; + return 1; + } + if (strcmp (arg, "gz") == 0) + { + compress_func = grub_install_compress_gzip; + return 1; + } + if (strcmp (arg, "xz") == 0) + { + compress_func = grub_install_compress_xz; + return 1; + } + if (strcmp (arg, "lzo") == 0) + { + compress_func = grub_install_compress_lzop; + return 1; + } + grub_util_error (_("Unrecognized compression `%s'"), arg); + case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE: + return 1; + default: + return 0; + } +} + +static int +decompressors (void) +{ + if (compress_func == grub_install_compress_gzip) + { + grub_install_push_module ("gzio"); + return 1; + } + if (compress_func == grub_install_compress_xz) + { + grub_install_push_module ("xzio"); + grub_install_push_module ("gcry_crc"); + return 2; + } + if (compress_func == grub_install_compress_lzop) + { + grub_install_push_module ("lzopio"); + grub_install_push_module ("adler32"); + grub_install_push_module ("gcry_crc"); + return 3; + } + return 0; +} + +void +grub_install_make_image_wrap_file (const char *dir, const char *prefix, + FILE *fp, const char *outname, + char *memdisk_path, + char *config_path, + const char *mkimage_target, int note, + grub_compression_t comp) +{ + const struct grub_install_image_target_desc *tgt; + const char *const compnames[] = + { + [GRUB_COMPRESSION_AUTO] = "auto", + [GRUB_COMPRESSION_NONE] = "none", + [GRUB_COMPRESSION_XZ] = "xz", + [GRUB_COMPRESSION_LZMA] = "lzma", + }; + grub_size_t slen = 1; + char *s, *p; + char **pk, **md; + int dc = decompressors (); + + if (memdisk_path) + slen += 20 + grub_strlen (memdisk_path); + if (config_path) + slen += 20 + grub_strlen (config_path); + + for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) + slen += 20 + grub_strlen (*pk); + + for (md = modules.entries; *md; md++) + { + slen += 10 + grub_strlen (*md); + } + + p = s = xmalloc (slen); + if (memdisk_path) + { + p = grub_stpcpy (p, "--memdisk '"); + p = grub_stpcpy (p, memdisk_path); + *p++ = '\''; + *p++ = ' '; + } + if (config_path) + { + p = grub_stpcpy (p, "--config '"); + p = grub_stpcpy (p, config_path); + *p++ = '\''; + *p++ = ' '; + } + for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) + { + p = grub_stpcpy (p, "--pubkey '"); + p = grub_stpcpy (p, *pk); + *p++ = '\''; + *p++ = ' '; + } + + for (md = modules.entries; *md; md++) + { + *p++ = '\''; + p = grub_stpcpy (p, *md); + *p++ = '\''; + *p++ = ' '; + } + + *p = '\0'; + + grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'" + " --output '%s' " + "--format '%s' --compression '%s' %s %s\n", + dir, prefix, + outname, mkimage_target, + compnames[comp], note ? "--note" : "", s); + + tgt = grub_install_get_image_target (mkimage_target); + if (!tgt) + grub_util_error (_("unknown target format %s\n"), mkimage_target); + + grub_install_generate_image (dir, prefix, fp, outname, + modules.entries, memdisk_path, + pubkeys, npubkeys, config_path, tgt, + note, comp); + while (dc--) + grub_install_pop_module (); +} + +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *mkimage_target, int note, + grub_compression_t comp) +{ + FILE *fp; + + fp = grub_util_fopen (outname, "wb"); + if (! fp) + grub_util_error (_("cannot open `%s': %s"), outname, + strerror (errno)); + grub_install_make_image_wrap_file (dir, prefix, fp, outname, + memdisk_path, config_path, + mkimage_target, note, comp); + fflush (fp); + fsync (fileno (fp)); + fclose (fp); +} + +static void +copy_by_ext (const char *srcd, + const char *dstd, + const char *extf, + int req) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (srcd); + if (!d && !req) + return; + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + const char *ext = strrchr (de->d_name, '.'); + if (ext && strcmp (ext, extf) == 0) + { + char *srcf = grub_util_path_concat (2, srcd, de->d_name); + char *dstf = grub_util_path_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + } + grub_util_fd_closedir (d); +} + +static void +copy_all (const char *srcd, + const char *dstd) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (srcd); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + char *srcf; + char *dstf; + if (strcmp (de->d_name, ".") == 0 + || strcmp (de->d_name, "..") == 0) + continue; + srcf = grub_util_path_concat (2, srcd, de->d_name); + if (grub_util_is_special_file (srcf) + || grub_util_is_directory (srcf)) + continue; + dstf = grub_util_path_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + grub_util_fd_closedir (d); +} + +static void +copy_locales (const char *dstd) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + const char *locale_dir = grub_util_get_localedir (); + + d = grub_util_fd_opendir (LOCALEDIR); + if (!d) + { + grub_util_warn (_("cannot open directory `%s': %s"), + locale_dir, grub_util_fd_strerror ()); + return; + } + + while ((de = grub_util_fd_readdir (d))) + { + char *srcf; + char *dstf; + if (strcmp (de->d_name, ".") == 0) + continue; + if (strcmp (de->d_name, "..") == 0) + continue; + srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name, + "LC_MESSAGES", PACKAGE, ".mo"); + dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo"); + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } + grub_util_fd_closedir (d); +} + +static struct +{ + enum grub_install_plat val; + const char *cpu; + const char *platform; +} platforms[] = + { + { GRUB_INSTALL_PLATFORM_I386_PC, "i386", "pc" }, + { GRUB_INSTALL_PLATFORM_I386_EFI, "i386", "efi" }, + { GRUB_INSTALL_PLATFORM_I386_QEMU, "i386", "qemu" }, + { GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386", "coreboot" }, + { GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386", "multiboot" }, + { GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386", "ieee1275" }, + { GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64", "efi" }, + { GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel", "loongson" }, + { GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel", "qemu_mips" }, + { GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips", "qemu_mips" }, + { GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel", "arc" }, + { GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips", "arc" }, + { GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, "sparc64", "ieee1275" }, + { GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc", "ieee1275" }, + { GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64", "efi" }, + { GRUB_INSTALL_PLATFORM_ARM_EFI, "arm", "efi" }, + { GRUB_INSTALL_PLATFORM_ARM_UBOOT, "arm", "uboot" }, + }; + +char * +grub_install_get_platform_name (enum grub_install_plat platid) +{ + return xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); +} + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid) +{ + return platforms[platid].cpu; +} + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid) +{ + return platforms[platid].platform; +} + + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid) +{ + char *dst_platform, *dst_locale, *dst_fonts; + const char *pkgdatadir = grub_util_get_pkgdatadir (); + + { + char *platform; + platform = xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); + dst_platform = grub_util_path_concat (2, dst, platform); + free (platform); + } + dst_locale = grub_util_path_concat (2, dst, "locale"); + dst_fonts = grub_util_path_concat (2, dst, "fonts"); + grub_install_mkdir_p (dst_platform); + grub_install_mkdir_p (dst_locale); + clean_grub_dir (dst); + clean_grub_dir (dst_platform); + clean_grub_dir (dst_locale); + + if (install_modules.is_default) + copy_by_ext (src, dst_platform, ".mod", 1); + else + { + struct grub_util_path_list *path_list, *p; + + path_list = grub_util_resolve_dependencies (src, "moddep.lst", + install_modules.entries); + for (p = path_list; p; p = p->next) + { + char *srcf = grub_util_path_concat_ext (2, src, p->name, ".mo"); + char *dstf = grub_util_path_concat_ext (2, dst, p->name, ".mo"); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + } + + const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o", + "moddep.lst", "command.lst", + "fs.lst", "partmap.lst", + "parttool.lst", + "video.lst", "crypto.lst", + "terminal.lst" }; + size_t i; + + for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++) + { + char *srcf = grub_util_path_concat (2, src, pkglib_DATA[i]); + char *dstf = grub_util_path_concat (2, dst_platform, pkglib_DATA[i]); + if (i == 0 || i == 1) + grub_install_compress_file (srcf, dstf, 0); + else + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + + if (install_locales.is_default) + { + char *srcd = grub_util_path_concat (2, src, "po"); + copy_by_ext (srcd, dst_locale, ".mo", 0); + copy_locales (dst_locale); + free (srcd); + } + else + { + for (i = 0; i < install_locales.n_entries; i++) + { + char *srcf = grub_util_path_concat_ext (3, src, + "po", + install_locales.entries[i], + ".mo"); + char *dstf = grub_util_path_concat_ext (2, dst_locale, + install_locales.entries[i], + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + free (srcf); + srcf = grub_util_path_concat_ext (4, + LOCALEDIR, + install_locales.entries[i], + "LC_MESSAGES", + PACKAGE, + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + grub_util_error (_("cannot find locale `%s'"), + install_locales.entries[i]); + } + } + + if (install_themes.is_default) + { + install_themes.is_default = 0; + install_themes.n_entries = 1; + install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0])); + install_themes.entries[0] = xstrdup ("starfield"); + install_themes.entries[1] = NULL; + } + + for (i = 0; i < install_themes.n_entries; i++) + { + char *srcf = grub_util_path_concat (4, pkgdatadir, "themes", + install_themes.entries[i], + "theme.txt"); + if (grub_util_is_regular (srcf)) + { + char *srcd = grub_util_path_concat (3, pkgdatadir, "themes", + install_themes.entries[i]); + char *dstd = grub_util_path_concat (3, dst, "themes", + install_themes.entries[i]); + grub_install_mkdir_p (dstd); + copy_all (srcd, dstd); + free (srcd); + free (dstd); + } + free (srcf); + } + + if (install_fonts.is_default) + { + install_fonts.is_default = 0; + install_fonts.n_entries = 1; + install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0])); + install_fonts.entries[0] = xstrdup ("unicode"); + install_fonts.entries[1] = NULL; + } + + grub_install_mkdir_p (dst_fonts); + + for (i = 0; i < install_fonts.n_entries; i++) + { + char *srcf = grub_util_path_concat_ext (2, pkgdatadir, + install_fonts.entries[i], + ".pf2"); + char *dstf = grub_util_path_concat_ext (2, dst_fonts, + install_fonts.entries[i], + ".pf2"); + + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } + + free (dst_platform); + free (dst_locale); + free (dst_fonts); +} + +enum grub_install_plat +grub_install_get_target (const char *src) +{ + char *fn; + grub_util_fd_t f; + char buf[2048]; + size_t r; + char *c, *pl, *p; + size_t i; + fn = grub_util_path_concat (2, src, "modinfo.sh"); + f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (f)) + grub_util_error (_("%s doesn't exist. Please specify --target or --directory"), + fn); + r = grub_util_fd_read (f, buf, sizeof (buf) - 1); + grub_util_fd_close (f); + buf[r] = '\0'; + c = strstr (buf, "grub_modinfo_target_cpu="); + if (!c || (c != buf && !grub_isspace (*(c-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + pl = strstr (buf, "grub_modinfo_platform="); + if (!pl || (pl != buf && !grub_isspace (*(pl-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + c += sizeof ("grub_modinfo_target_cpu=") - 1; + pl += sizeof ("grub_modinfo_platform=") - 1; + for (p = c; *p && !grub_isspace (*p); p++); + *p = '\0'; + for (p = pl; *p && !grub_isspace (*p); p++); + *p = '\0'; + + for (i = 0; i < ARRAY_SIZE (platforms); i++) + if (strcmp (platforms[i].cpu, c) == 0 + && strcmp (platforms[i].platform, pl) == 0) + { + free (fn); + return platforms[i].val; + } + grub_util_error (_("Unknown platform `%s-%s'"), c, pl); +} + + +void +grub_util_unlink_recursive (const char *name) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (name); + + while ((de = grub_util_fd_readdir (d))) + { + char *fp; + if (strcmp (de->d_name, ".") == 0) + continue; + if (strcmp (de->d_name, "..") == 0) + continue; + fp = grub_util_path_concat (2, name, de->d_name); + if (grub_util_is_special_file (fp)) + { + free (fp); + continue; + } + if (grub_util_is_regular (fp)) + grub_util_unlink (fp); + else if (grub_util_is_directory (fp)) + grub_util_unlink_recursive (fp); + free (fp); + } + grub_util_rmdir (name); + grub_util_fd_closedir (d); +} diff --git a/util/grub-install.c b/util/grub-install.c new file mode 100644 index 000000000..100f09379 --- /dev/null +++ b/util/grub-install.c @@ -0,0 +1,1539 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 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 + +#include "argp.h" + +#include "progname.h" + +static char *target; +static int removable = 0; +static int recheck = 0; +static int update_nvram = 1; +static char *install_device = NULL; +static char *debug_image = NULL; +static char *rootdir = NULL; +static char *bootdir = NULL; +static int allow_floppy = 0; +static int force_file_id = 0; +static char *disk_module = NULL; +static char *efidir = NULL; +static int force = 0; +static int have_abstractions = 0; +static int have_cryptodisk = 0; +static char * bootloader_id; +static int have_load_cfg = 0; +static FILE * load_cfg_f = NULL; +static char *load_cfg; + +enum + { + OPTION_BOOT_DIRECTORY = 0x301, + OPTION_ROOT_DIRECTORY, + OPTION_TARGET, + OPTION_SETUP, + OPTION_MKRELPATH, + OPTION_MKDEVICEMAP, + OPTION_PROBE, + OPTION_EDITENV, + OPTION_ALLOW_FLOPPY, + OPTION_RECHECK, + OPTION_FORCE, + OPTION_FORCE_FILE_ID, + OPTION_MODULE, + OPTION_NO_NVRAM, + OPTION_REMOVABLE, + OPTION_BOOTLOADER_ID, + OPTION_EFI_DIRECTORY, + OPTION_FONT, + OPTION_DEBUG, + OPTION_DEBUG_IMAGE, + OPTION_NO_FLOPPY, + OPTION_DISK_MODULE + }; + +static int fs_probe = 1; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_FORCE_FILE_ID: + force_file_id = 1; + return 0; + case 's': + fs_probe = 0; + return 0; + + /* Accept and ignore for compatibility. */ + case OPTION_FONT: + case OPTION_SETUP: + case OPTION_MKRELPATH: + case OPTION_PROBE: + case OPTION_EDITENV: + case OPTION_MKDEVICEMAP: + case OPTION_NO_FLOPPY: + return 0; + case OPTION_ROOT_DIRECTORY: + /* Accept for compatibility. */ + free (rootdir); + rootdir = xstrdup (arg); + return 0; + + case OPTION_BOOT_DIRECTORY: + free (bootdir); + bootdir = xstrdup (arg); + return 0; + + case OPTION_EFI_DIRECTORY: + free (efidir); + efidir = xstrdup (arg); + return 0; + + case OPTION_DISK_MODULE: + free (disk_module); + disk_module = xstrdup (arg); + return 0; + + case OPTION_TARGET: + free (target); + target = xstrdup (arg); + return 0; + + case OPTION_DEBUG_IMAGE: + free (debug_image); + debug_image = xstrdup (arg); + return 0; + + case OPTION_NO_NVRAM: + update_nvram = 0; + return 0; + + case OPTION_FORCE: + force = 1; + return 0; + + case OPTION_RECHECK: + recheck = 1; + return 0; + + case OPTION_REMOVABLE: + removable = 1; + return 0; + + case OPTION_ALLOW_FLOPPY: + allow_floppy = 1; + return 0; + + case OPTION_DEBUG: + verbosity++; + return 0; + + case OPTION_BOOTLOADER_ID: + free (bootloader_id); + bootloader_id = xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + if (install_device) + grub_util_error ("%s", _("More than one install device?")); + install_device = xstrdup (arg); + return 0; + + default: + return ARGP_ERR_UNKNOWN; + } +} + + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"), + 0, N_("install GRUB images under the directory DIR/%s instead of the %s directory"), 2}, + {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"), + OPTION_HIDDEN, 0, 2}, + {"font", OPTION_FONT, N_("FILE"), + OPTION_HIDDEN, 0, 2}, + {"target", OPTION_TARGET, N_("TARGET"), + /* TRANSLATORS: "TARGET" as in "target platform". */ + 0, N_("install GRUB for TARGET platform [default=%s]"), 2}, + {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2}, + {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0, + /* TRANSLATORS: "may break" doesn't just mean that option wouldn't have any + effect but that it will make the resulting install unbootable from HDD. */ + N_("make the drive also bootable as floppy (default for fdX devices)." + " May break on some BIOSes."), 2}, + {"recheck", OPTION_RECHECK, 0, 0, + N_("delete device map if it already exists"), 2}, + {"force", OPTION_FORCE, 0, 0, + N_("install even if problems are detected"), 2}, + {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0, + N_("use identifier file even if UUID is available"), 2}, + {"disk-module", OPTION_MODULE, N_("MODULE"), 0, + N_("disk module to use (biosdisk or native). " + "This option is only available on BIOS target."), 2}, + {"no-nvram", OPTION_NO_NVRAM, 0, 0, + N_("don't update the `boot-device' NVRAM variable. " + "This option is only available on IEEE1275 targets."), 2}, + + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, "STR", OPTION_HIDDEN, 0, 2}, + {"removable", OPTION_REMOVABLE, 0, 0, + N_("the installation device is removable. " + "This option is only available on EFI."), 2}, + {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0, + N_("the ID of bootloader. This option is only available on EFI."), 2}, + {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0, + N_("use DIR as the EFI System Partition root."), 2}, + {"skip-fs-probe",'s',0, 0, + N_("do not probe for filesystems in DEVICE"), 0}, + + {0, 0, 0, 0, 0, 0} +}; + +static const char * +get_default_platform (void) +{ +#ifdef __powerpc__ + return "powerpc-ieee1275"; +#elif defined (__sparc__) || defined (__sparc64__) + return "sparc64-ieee1275"; +#elif defined (__MIPSEL__) + return "mipsel-loongson"; +#elif defined (__MIPSEB__) + return "mips-arc"; +#elif defined (__ia64__) + return "ia64-efi"; +#elif defined (__arm__) + return "arm-uboot"; +#elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) + return grub_install_get_default_x86_platform (); +#else + return NULL; +#endif +} + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case OPTION_BOOT_DIRECTORY: + return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME); + case OPTION_TARGET: + return xasprintf (text, get_default_platform ()); + case ARGP_KEY_HELP_POST_DOC: + return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME); + default: + return grub_install_help_filter (key, text, input); + } +} + +/* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you + install to. */ +struct argp argp = { + options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"), + N_("Install GRUB on your drive.")"\v" + N_("INSTALL_DEVICE must be system device filename.\n" + "%s copies GRUB images into %s. On some platforms, it" + " may also install GRUB into the boot sector."), + NULL, help_filter, NULL +}; + +static int +probe_raid_level (grub_disk_t disk) +{ + /* disk might be NULL in the case of a LVM physical volume with no LVM + signature. Ignore such cases here. */ + if (!disk) + return -1; + + if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID) + return -1; + + if (disk->name[0] != 'm' || disk->name[1] != 'd') + return -1; + + if (!((struct grub_diskfilter_lv *) disk->data)->segments) + return -1; + return ((struct grub_diskfilter_lv *) disk->data)->segments->type; +} + +static void +probe_mods (grub_disk_t disk) +{ + grub_partition_t part; + grub_disk_memberlist_t list = NULL, tmp; + int raid_level; + + if (disk->partition == NULL) + grub_util_info ("no partition map found for %s", disk->name); + + for (part = disk->partition; part; part = part->parent) + { + char buf[50]; + if (strcmp (part->partmap->name, "openbsd") == 0 + || strcmp (part->partmap->name, "netbsd") == 0) + { + grub_install_push_module ("part_bsd"); + continue; + } + snprintf (buf, sizeof (buf), "part_%s", part->partmap->name); + grub_install_push_module (buf); + } + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) + { + grub_diskfilter_get_partmap (disk, grub_install_push_module); + have_abstractions = 1; + } + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID + && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 || + grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0)) + grub_install_push_module ("lvm"); + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID + && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0) + grub_install_push_module ("ldm"); + + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + grub_util_cryptodisk_get_abstraction (disk, + grub_install_push_module); + have_abstractions = 1; + have_cryptodisk = 1; + } + + raid_level = probe_raid_level (disk); + if (raid_level >= 0) + { + grub_install_push_module ("diskfilter"); + if (disk->dev->raidname) + grub_install_push_module (disk->dev->raidname (disk)); + } + if (raid_level == 5) + grub_install_push_module ("raid5rec"); + if (raid_level == 6) + grub_install_push_module ("raid6rec"); + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->memberlist) + list = disk->dev->memberlist (disk); + while (list) + { + probe_mods (list->disk); + tmp = list->next; + free (list); + list = tmp; + } +} + +static int +have_bootdev (enum grub_install_plat pl) +{ + switch (pl) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + return 1; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + return 0; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + return 0; + } + return 0; +} + +static void +probe_cryptodisk_uuid (grub_disk_t disk) +{ + grub_disk_memberlist_t list = NULL, tmp; + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->memberlist) + { + list = disk->dev->memberlist (disk); + } + while (list) + { + probe_cryptodisk_uuid (list->disk); + tmp = list->next; + free (list); + list = tmp; + } + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + const char *uuid = grub_util_cryptodisk_get_uuid (disk); + if (!load_cfg_f) + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + + fprintf (load_cfg_f, "cryptomount -u %s\n", + uuid); + } +} + +static int +is_same_disk (const char *a, const char *b) +{ + while (1) + { + if ((*a == ',' || *a == '\0') && (*b == ',' || *b == '\0')) + return 1; + if (*a != *b) + return 0; + if (*a == '\\') + { + if (a[1] != b[1]) + return 0; + a += 2; + b += 2; + continue; + } + a++; + b++; + } +} + +char * +get_rndstr (void) +{ + grub_uint8_t rnd[15]; + const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5; + char * ret = xmalloc (sz + 1); + size_t i; + if (grub_get_random (rnd, sizeof (rnd))) + grub_util_error ("%s", _("couldn't retrieve random data")); + for (i = 0; i < sz; i++) + { + grub_size_t b = i * 5; + grub_uint8_t r; + grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT; + grub_size_t f2; + if (f1 > 5) + f1 = 5; + f2 = 5 - f1; + r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1); + if (f2) + r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1; + if (r < 10) + ret[i] = '0' + r; + else + ret[i] = 'a' + (r - 10); + } + ret[sz] = '\0'; + return ret; +} + +static char * +escape (const char *in) +{ + char *ptr; + char *ret; + int overhead = 0; + + for (ptr = (char*)in; *ptr; ptr++) + if (*ptr == '\'') + overhead += 3; + ret = grub_malloc (ptr - in + overhead + 1); + if (!ret) + return NULL; + + grub_strchrsub (ret, in, '\'', "'\\''"); + return ret; +} + +static struct grub_util_config config; + +static void +device_map_check_duplicates (const char *dev_map) +{ + FILE *fp; + char buf[1024]; /* XXX */ + size_t alloced = 8; + size_t filled = 0; + char **d; + size_t i; + + d = xmalloc (alloced * sizeof (d[0])); + + if (dev_map[0] == '\0') + return; + + fp = grub_util_fopen (dev_map, "r"); + if (! fp) + return; + + while (fgets (buf, sizeof (buf), fp)) + { + char *p = buf; + char *e; + + /* Skip leading spaces. */ + while (*p && grub_isspace (*p)) + p++; + + /* If the first character is `#' or NUL, skip this line. */ + if (*p == '\0' || *p == '#') + continue; + + if (*p != '(') + continue; + + p++; + + e = p; + p = strchr (p, ')'); + if (! p) + continue; + + if (filled >= alloced) + { + alloced *= 2; + d = xrealloc (d, alloced * sizeof (d[0])); + } + + *p = '\0'; + + d[filled++] = xstrdup (e); + } + + fclose (fp); + + qsort (d, filled, sizeof (d[0]), (int (*) (const void *, const void *))strcmp); + + for (i = 0; i + 1 < filled; i++) + if (strcmp (d[i], d[i+1]) == 0) + { + grub_util_error ("the drive %s is defined multiple times in the device map %s", + d[i], dev_map); + } + + for (i = 0; i < filled; i++) + free (d[i]); + + free (d); +} + +static grub_err_t +write_to_disk (grub_device_t dev, const char *fn) +{ + char *core_img; + size_t core_size; + grub_err_t err; + + core_size = grub_util_get_image_size (fn); + + core_img = grub_util_read_image (fn); + + err = grub_disk_write (dev->disk, 0, 0, + core_size, core_img); + free (core_img); + return err; +} + +static int +is_prep_partition (grub_device_t dev) +{ + if (!dev->disk) + return 0; + if (!dev->disk->partition) + return 0; + if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0) + return (dev->disk->partition->msdostype == 0x41); + + if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0) + { + struct grub_gpt_partentry gptdata; + grub_partition_t p = dev->disk->partition; + int ret = 0; + dev->disk->partition = dev->disk->partition->parent; + + if (grub_disk_read (dev->disk, p->offset, p->index, + sizeof (gptdata), &gptdata) == 0) + { + const grub_gpt_part_type_t template = { + grub_cpu_to_le32_compile_time (0x9e1a2d38), + grub_cpu_to_le16_compile_time (0xc612), + grub_cpu_to_le16_compile_time (0x4316), + { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b } + }; + + ret = grub_memcmp (&template, &gptdata.type, + sizeof (template)) == 0; + } + dev->disk->partition = p; + return ret; + } + + return 0; +} + +static int +is_prep_empty (grub_device_t dev) +{ + grub_disk_addr_t dsize, addr; + grub_uint32_t buffer[32768]; + + dsize = grub_disk_get_size (dev->disk); + for (addr = 0; addr < dsize; + addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE) + { + grub_size_t sz = sizeof (buffer); + grub_uint32_t *ptr; + + if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr) + sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE; + grub_disk_read (dev->disk, addr, 0, sz, buffer); + + if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0) + return 1; + + for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++) + if (*ptr) + return 0; + } + + return 1; +} + +int +main (int argc, char *argv[]) +{ + int is_efi = 0; + const char *efi_distributor = NULL; + const char *efi_file = NULL; + char **grub_devices; + grub_fs_t grub_fs; + grub_device_t grub_dev = NULL; + enum grub_install_plat platform; + char *grubdir, *device_map; + char **curdev, **curdrive; + char **grub_drives; + char *relative_grubdir; + char **efidir_device_names = NULL; + grub_device_t efidir_grub_dev = NULL; + char *efidir_grub_devname; + + grub_util_host_init (&argc, &argv); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (verbosity > 1) + grub_env_set ("debug", "all"); + + grub_util_load_config (&config); + + if (!bootloader_id && config.grub_distributor) + { + char *ptr; + bootloader_id = xstrdup (config.grub_distributor); + for (ptr = bootloader_id; *ptr && *ptr != ' '; ptr++) + if (*ptr >= 'A' && *ptr <= 'Z') + *ptr = *ptr - 'A' + 'a'; + *ptr = '\0'; + } + if (!bootloader_id || bootloader_id[0] == '\0') + { + free (bootloader_id); + bootloader_id = xstrdup ("grub"); + } + + if (!grub_install_source_directory) + { + if (!target) + { + const char * t; + t = get_default_platform (); + if (!t) + grub_util_error ("%s", + _("Unable to determine your platform." + " Use --target.") + ); + target = xstrdup (t); + } + grub_install_source_directory + = grub_util_path_concat (2, grub_util_get_pkglibdir (), target); + } + + platform = grub_install_get_target (grub_install_source_directory); + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + if (!disk_module) + disk_module = xstrdup ("biosdisk"); + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + break; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + disk_module = xstrdup ("native"); + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + if (!install_device) + grub_util_error ("%s", _("install device isn't specified")); + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + free (install_device); + install_device = NULL; + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + if (!bootdir) + bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME); + + { + char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME); + grub_install_mkdir_p (t); + grubdir = canonicalize_file_name (t); + if (!grubdir) + grub_util_error (_("failed to get canonical path of `%s'"), t); + free (t); + } + device_map = grub_util_path_concat (2, grubdir, "device.map"); + + if (recheck) + grub_util_unlink (device_map); + + device_map_check_duplicates (device_map); + grub_util_biosdisk_init (device_map); + + /* Initialize all modules. */ + grub_init_all (); + grub_gcry_init_all (); + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + is_efi = 1; + break; + default: + is_efi = 0; + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + /* Find the EFI System Partition. */ + + if (is_efi) + { + grub_fs_t fs; + free (install_device); + install_device = NULL; + if (!efidir) + { + char *d = grub_util_path_concat (2, bootdir, "efi"); + char *dr = NULL; + if (!grub_util_is_directory (d)) + { + free (d); + d = grub_util_path_concat (2, bootdir, "EFI"); + } + /* + The EFI System Partition may have been given directly using + --root-directory. + */ + if (!grub_util_is_directory (d) + && rootdir && grub_strcmp (rootdir, "/") != 0) + { + free (d); + d = xstrdup (rootdir); + } + if (grub_util_is_directory (d)) + dr = grub_make_system_path_relative_to_its_root (d); + /* Is it a mount point? */ + if (dr && dr[0] == '\0') + efidir = d; + else + free (d); + free (dr); + } + if (!efidir) + grub_util_error ("%s", _("cannot find EFI directory")); + efidir_device_names = grub_guess_root_devices (efidir); + if (!efidir_device_names || !efidir_device_names[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + efidir); + install_device = efidir_device_names[0]; + + for (curdev = efidir_device_names; *curdev; curdev++) + grub_util_pull_device (*curdev); + + efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]); + if (!efidir_grub_devname) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + efidir_device_names[0]); + + efidir_grub_dev = grub_device_open (efidir_grub_devname); + if (! efidir_grub_dev) + grub_util_error ("%s", grub_errmsg); + + fs = grub_fs_probe (efidir_grub_dev); + if (! fs) + grub_util_error ("%s", grub_errmsg); + + if (grub_strcmp (fs->name, "fat") != 0) + grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir); + + /* The EFI specification requires that an EFI System Partition must + contain an "EFI" subdirectory, and that OS loaders are stored in + subdirectories below EFI. Vendors are expected to pick names that do + not collide with other vendors. To minimise collisions, we use the + name of our distributor if possible. + */ + char *t; + efi_distributor = bootloader_id; + if (removable) + { + /* The specification makes stricter requirements of removable + devices, in order that only one image can be automatically loaded + from them. The image must always reside under /EFI/BOOT, and it + must have a specific file name depending on the architecture. + */ + efi_distributor = "BOOT"; + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file = "BOOTIA32.EFI"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file = "BOOTX64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file = "BOOTIA64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file = "BOOTARM.EFI"; + break; + default: + grub_util_error ("%s", _("You've found a bug")); + break; + } + } + else + { + /* It is convenient for each architecture to have a different + efi_file, so that different versions can be installed in parallel. + */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file = "grubia32.efi"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file = "grubx64.efi"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file = "grubia64.efi"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file = "grubarm.efi"; + break; + default: + efi_file = "grub.efi"; + break; + } + } + t = grub_util_path_concat (3, efidir, "EFI", efi_distributor); + free (efidir); + efidir = t; + grub_install_mkdir_p (efidir); + } + + grub_install_copy_files (grub_install_source_directory, + grubdir, platform); + + char *envfile = grub_util_path_concat (2, grubdir, "grubenv"); + if (!grub_util_is_regular (envfile)) + grub_util_create_envblk_file (envfile); + + size_t ndev = 0; + + /* Write device to a variable so we don't have to traverse /dev every time. */ + grub_devices = grub_guess_root_devices (grubdir); + if (!grub_devices || !grub_devices[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + grubdir); + + for (curdev = grub_devices; *curdev; curdev++) + { + grub_util_pull_device (*curdev); + ndev++; + } + + grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); + + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) + { + *curdrive = grub_util_get_grub_dev (*curdev); + if (! *curdrive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + *curdev); + } + *curdrive = 0; + + grub_dev = grub_device_open (grub_drives[0]); + if (! grub_dev) + grub_util_error ("%s", grub_errmsg); + + grub_fs = grub_fs_probe (grub_dev); + if (! grub_fs) + grub_util_error ("%s", grub_errmsg); + + grub_install_push_module (grub_fs->name); + + if (grub_dev->disk) + probe_mods (grub_dev->disk); + + for (curdrive = grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev = grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_mods (dev->disk); + grub_device_close (dev); + } + + if (!config.is_cryptodisk_enabled && have_cryptodisk) + grub_util_error (_("attempt to install to cryptodisk without cryptodisk enabled. " + "Set `%s' in file `%s'."), "GRUB_ENABLE_CRYPTODISK=1", + grub_util_get_config_filename ()); + + if (disk_module && grub_strcmp (disk_module, "ata") == 0) + grub_install_push_module ("pata"); + else if (disk_module && grub_strcmp (disk_module, "native") == 0) + { + grub_install_push_module ("pata"); + grub_install_push_module ("ahci"); + grub_install_push_module ("ohci"); + grub_install_push_module ("uhci"); + grub_install_push_module ("usbms"); + } + else if (disk_module && disk_module[0]) + grub_install_push_module (disk_module); + + relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir); + if (relative_grubdir[0] == '\0') + { + free (relative_grubdir); + relative_grubdir = xstrdup ("/"); + } + + char *platname = grub_install_get_platform_name (platform); + char *platdir; + { + char *t = grub_util_path_concat (2, grubdir, + platname); + platdir = canonicalize_file_name (t); + if (!platdir) + grub_util_error (_("failed to get canonical path of `%s'"), + t); + free (t); + } + load_cfg = grub_util_path_concat (2, platdir, + "load.cfg"); + + grub_util_unlink (load_cfg); + + if (debug_image && debug_image[0]) + { + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "set debug='%s'\n", + debug_image); + } + char *prefix_drive = NULL; + char *install_drive = NULL; + + if (install_device) + { + if (install_device[0] == '(' + && install_device[grub_strlen (install_device) - 1] == ')') + install_drive = xstrdup (install_device); + else + { + grub_util_pull_device (install_device); + install_drive = grub_util_get_grub_dev (install_device); + if (!install_drive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + install_device); + } + } + + if (!have_abstractions) + { + if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0) + || grub_drives[1] + || (!install_drive + && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) + || (install_drive && !is_same_disk (grub_drives[0], install_drive)) + || !have_bootdev (platform)) + { + char *uuid = NULL; + /* generic method (used on coreboot and ata mod). */ + if (!force_file_id && grub_fs->uuid && grub_fs->uuid (grub_dev, + &uuid)) + { + grub_print_error (); + grub_errno = 0; + uuid = NULL; + } + + if (!load_cfg_f) + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + if (uuid) + { + fprintf (load_cfg_f, "search.fs_uuid %s root ", + uuid); + grub_install_push_module ("search_fs_uuid"); + } + else + { + char *rndstr = get_rndstr (); + char *fl = grub_util_path_concat (3, grubdir, + "uuid", rndstr); + char *fldir = grub_util_path_concat (2, grubdir, + "uuid"); + char *relfl; + FILE *flf; + grub_install_mkdir_p (fldir); + flf = grub_util_fopen (fl, "w"); + if (!flf) + grub_util_error ("Can't create file: %s", strerror (errno)); + fclose (flf); + relfl = grub_make_system_path_relative_to_its_root (fl); + fprintf (load_cfg_f, "search.file %s root ", + relfl); + grub_install_push_module ("search_fs_file"); + } + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) + { + const char *map; + char *g = NULL; + grub_device_t dev; + if (curdrive == grub_drives) + dev = grub_dev; + else + dev = grub_device_open (*curdrive); + if (!dev) + continue; + + if (dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID) + { + grub_util_fprint_full_disk_name (load_cfg_f, + dev->disk->name, + dev); + fprintf (load_cfg_f, " "); + if (dev != grub_dev) + grub_device_close (dev); + continue; + } + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + + if (map) + { + grub_util_fprint_full_disk_name (load_cfg_f, map, dev); + fprintf (load_cfg_f, " "); + } + + + if (disk_module && disk_module[0] + && grub_strcmp (disk_module, "biosdisk") != 0) + g = grub_util_guess_baremetal_drive (*curdev); + else + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + g = grub_util_guess_bios_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + g = grub_util_guess_efi_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + { + const char * ofpath = grub_util_devname_to_ofpath (*curdev); + g = xasprintf ("ieee1275/%s", ofpath); + break; + } + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + g = grub_util_guess_baremetal_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance")); + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + if (g) + { + grub_util_fprint_full_disk_name (load_cfg_f, g, dev); + fprintf (load_cfg_f, " "); + } + if (dev != grub_dev) + grub_device_close (dev); + } + fprintf (load_cfg_f, "\n"); + char *escaped_relpath = escape (relative_grubdir); + fprintf (load_cfg_f, "set prefix=($root)'%s'\n", + escaped_relpath); + } + else + { + /* We need to hardcode the partition number in the core image's prefix. */ + char *p; + for (p = grub_drives[0]; *p; ) + { + if (*p == '\\' && p[1]) + { + p += 2; + continue; + } + if (*p == ',' || *p == '\0') + break; + p++; + } + prefix_drive = xasprintf ("(%s)", p); + } + } + else + { + if (config.is_cryptodisk_enabled) + { + if (grub_dev->disk) + probe_cryptodisk_uuid (grub_dev->disk); + + for (curdrive = grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev = grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_cryptodisk_uuid (dev->disk); + grub_device_close (dev); + } + } + prefix_drive = xasprintf ("(%s)", grub_drives[0]); + } + + char mkimage_target[200]; + const char *core_name = NULL; + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + core_name = "core.efi"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + core_name = "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s-elf", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + core_name = "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + core_name = "core.img"; + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + strcpy (mkimage_target, "sparc64-ieee1275-raw"); + core_name = "core.img"; + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + if (!core_name) + grub_util_error ("%s", _("You've found a bug")); + + if (load_cfg_f) + fclose (load_cfg_f); + + char *imgfile = grub_util_path_concat (2, platdir, + core_name); + char *prefix = xasprintf ("%s%s", prefix_drive ? : "", + relative_grubdir); + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /*prefix */ prefix, + /* output */ imgfile, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, + 0, GRUB_COMPRESSION_AUTO); + /* Backward-compatibility kludges. */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + { + char *dst = grub_util_path_concat (2, bootdir, "grub.elf"); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + { + char *dst = grub_util_path_concat (2, grubdir, "grub"); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + { + char *dst = grub_util_path_concat (2, platdir, "grub.efi"); + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /* prefix */ "", + /* output */ dst, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, + 0, GRUB_COMPRESSION_AUTO); + } + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + /* Perform the platform-dependent install */ + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + { + char *boot_img_src = grub_util_path_concat (2, + grub_install_source_directory, + "boot.img"); + char *boot_img = grub_util_path_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img, 1); + + grub_util_info ("grub_bios_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + !fs_probe ? "--skip-fs-probe" : "", + platdir, + device_map, + install_device); + + /* Now perform the installation. */ + grub_util_bios_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy); + break; + } + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + { + char *boot_img_src = grub_util_path_concat (2, + grub_install_source_directory, + "boot.img"); + char *boot_img = grub_util_path_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img, 1); + + grub_util_info ("grub_sparc_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + !fs_probe ? "--skip-fs-probe" : "", + platdir, + device_map, + install_drive); + + /* Now perform the installation. */ + grub_util_sparc_setup (platdir, "boot.img", "core.img", + install_device, force, + fs_probe, allow_floppy); + break; + } + + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + /* If a install device is defined, copy the core.elf to PReP partition. */ + if (install_device && install_device[0]) + { + grub_device_t ins_dev; + ins_dev = grub_device_open (install_drive); + if (!ins_dev || !is_prep_partition (ins_dev)) + { + grub_util_error ("%s", _("the chosen partition is not a PReP partition")); + } + if (is_prep_empty (ins_dev)) + { + if (write_to_disk (ins_dev, imgfile)) + grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); + } + else + { + char *s = xasprintf ("dd if=/dev/zero of=%s", install_device); + grub_util_error ("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'", + s); + } + grub_device_close (ins_dev); + } + /* fallthrough. */ + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + if (update_nvram) + { + if (platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275 + || !install_device + || install_device[0] == '\0') + { + const char *dev; + char *relpath; + int partno; + relpath = grub_make_system_path_relative_to_its_root (imgfile); + partno = grub_dev->disk->partition + ? grub_dev->disk->partition->number + 1 : 0; + dev = grub_util_get_os_disk (grub_devices[0]); + grub_install_register_ieee1275 (0, dev, + partno, relpath); + } + else + grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device), + 0, NULL); + } + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + grub_install_sgi_setup (install_device, imgfile, "grub"); + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + { + char *dst = grub_util_path_concat (2, efidir, "grub.efi"); + /* For old macs. Suggested by Peter Jones. */ + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + { + char *dst = grub_util_path_concat (2, efidir, efi_file); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + if (!removable) + { + char * efidir_disk; + int efidir_part; + char * efifile_path; + + /* Try to make this image bootable using the EFI Boot Manager, if available. */ + if (!efi_distributor || efi_distributor[0] == '\0') + grub_util_error ("%s", "EFI distributor id isn't specified."); + efidir_disk = grub_util_get_os_disk (efidir_device_names[0]); + efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1; + efifile_path = xasprintf ("\\EFI\\%s\\%s", + efi_distributor, + efi_file); + grub_install_register_efi (efidir_disk, efidir_part, + efifile_path, efi_distributor); + } + break; + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + grub_util_warn ("%s", + _("WARNING: no platform-specific install was performed")); + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + fprintf (stderr, "%s\n", _("Installation finished. No error reported.")); + + /* Free resources. */ + grub_gcry_fini_all (); + grub_fini_all (); + + return 0; +} diff --git a/util/grub-install.in b/util/grub-install.in deleted file mode 100644 index c022a6bb9..000000000 --- a/util/grub-install.in +++ /dev/null @@ -1,829 +0,0 @@ -#! /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. -sbindir="@sbindir@" -sysconfdir="@sysconfdir@" - -host_os=@host_os@ -target= - -grub_probe="${sbindir}/@grub_probe@" -grub_editenv="${bindir}/@grub_editenv@" -grub_mkrelpath="${bindir}/@grub_mkrelpath@" -rootdir= -bootdir= -grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`" - -install_device= -force_lba= -recheck=no -debug=no -debug_image= - -update_nvram=yes - -removable=no -efi_quiet=-q - -# Get GRUB_DISTRIBUTOR. -if test -f "${sysconfdir}/default/grub" ; then - . "${sysconfdir}/default/grub" -fi - -bootloader_id="$(echo "$GRUB_DISTRIBUTOR" | tr 'A-Z' 'a-z' | cut -d' ' -f1)" -if test -z "$bootloader_id"; then - bootloader_id=grub -fi - -disk_module=unspecified - -# Usage: usage -# Print the usage. -usage () { - # TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you - # install to. - gettext_printf "Usage: %s [OPTION] [INSTALL_DEVICE]" "$self" - echo - gettext "Install GRUB on your drive." ; echo - echo - print_option_help "-h, --help" "$(gettext "print this message and exit")" - grub_print_install_files_help - - dirmsg="$(gettext_printf "install GRUB images under the directory DIR/%s instead of the %s directory" "@grubdirname@" "$grubdir")" - print_option_help "--boot-directory=$(gettext "DIR")" "$dirmsg" - # TRANSLATORS: "TARGET" as in "target platform". - target_trans="$(gettext "TARGET")" - # TRANSLATORS: "current" refers to the platform user's currently running on - print_option_help "--target=$target_trans" "$(gettext "install GRUB for TARGET platform [default=current]")" - print_option_help "--grub-setup=$(gettext "FILE")" "$(gettext "use FILE as grub-setup")" - print_option_help "--grub-mkrelpath=$(gettext "FILE")" "$(gettext "use FILE as grub-mkrelpath")" - print_option_help "--grub-probe=$(gettext "FILE")" "$(gettext "use FILE as grub-probe")" - print_option_help "--grub-editenv=$(gettext "FILE")" "$(gettext "use FILE as grub-editenv")" - # TRANSLATORS: "may break" doesn't just mean that option wouldn't have any - # effect but that it will make the resulting install unbootable from HDD. - print_option_help "--allow-floppy" "$(gettext "make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes.")" - print_option_help "--recheck" "$(gettext "delete device map if it already exists")" - print_option_help "--force" "$(gettext "install even if problems are detected")" - print_option_help "--force-file-id" "$(gettext "use identifier file even if UUID is available")" - print_option_help "--disk-module=$(gettext "MODULE")" "$(gettext "disk module to use (biosdisk or native). This option is only available on BIOS target.")" - print_option_help "--no-nvram" "$(gettext "don't update the \`boot-device' NVRAM variable. This option is only available on IEEE1275 targets.")" - print_option_help "--removable" "$(gettext "the installation device is removable. This option is only available on EFI.")" - print_option_help "--bootloader-id=$(gettext "ID")" "$(gettext "the ID of bootloader. This option is only available on EFI.")" - print_option_help "--efi-directory=$(gettext "DIR")" "$(gettext "use DIR as the EFI System Partition root.")" -echo -gettext "INSTALL_DEVICE must be system device filename.";echo -echo - -gettext_printf "%s copies GRUB images into %s. On some platforms, it -may also install GRUB into the boot sector.\n" "$self" "$grubdir";echo -echo -gettext "Report bugs to ."; echo -} - -allow_floppy="" -force_file_id= -efidir= - -# Check the arguments. -while test $# -gt 0 -do - grub_process_install_options "$@" - case "$grub_process_install_options_consumed" in - 1) shift; continue;; - 2) shift; shift; continue;; - esac - - option=$1 - shift - - case "$option" in - -h | --help) - usage - exit 0 ;; - - --force-file-id) - force_file_id=y ;; - -# Accept and ignore for compatibility - --font) - shift;; - --font=*) - ;; - -# Accept for compatibility - --root-directory) - rootdir="`argument $option "$@"`"; shift;; - --root-directory=*) - rootdir="`echo "$option" | sed 's/--root-directory=//'`" ;; - - --boot-directory) - bootdir="`argument $option "$@"`"; shift;; - --boot-directory=*) - bootdir="`echo "$option" | sed 's/--boot-directory=//'`" ;; - - --efi-directory) - efidir="`argument $option "$@"`"; shift;; - --efi-directory=*) - efidir="`echo "$option" | sed 's/--efi-directory=//'`" ;; - - --target) - target="`argument $option "$@"`"; shift;; - --target=*) - target="`echo "$option" | sed 's/--target=//'`" ;; - - --grub-setup) - grub_setup="`argument "$option" "$@"`"; shift;; - --grub-setup=*) - grub_setup="`echo "$option" | sed 's/--grub-setup=//'`" ;; - - --bootloader-id) - bootloader_id="`argument $option "$@"`"; shift;; - --bootloader-id=*) - bootloader_id="`echo "$option" | sed 's/--bootloader-id=//'`" ;; - - --grub-mkrelpath) - grub_mkrelpath="`argument "$option" "$@"`"; shift;; - --grub-mkrelpath=*) - grub_mkrelpath="`echo "$option" | sed 's/--grub-mkrelpath=//'`" ;; - - # Ignore: for compatibility - --grub-mkdevicemap) - shift;; - --grub-mkdevicemap=*) - ;; - - --grub-probe) - grub_probe="`argument "$option" "$@"`"; shift;; - --grub-probe=*) - grub_probe="`echo "$option" | sed 's/--grub-probe=//'`" ;; - - --grub-editenv) - grub_editenv="`argument "$option" "$@"`"; shift;; - --grub-editenv=*) - grub_editenv="`echo "$option" | sed 's/--grub-editenv=//'`" ;; - - --no-floppy) - ;; - --recheck) - recheck=yes ;; - --removable) - removable=yes ;; - - --allow-floppy) - allow_floppy="--allow-floppy" ;; - - --disk-module) - disk_module="`argument "$option" "$@"`"; shift; - ;; - --disk-module=*) - disk_module="`echo "$option" | sed 's/--disk-module=//'`" - ;; - - --no-nvram) - update_nvram=no ;; - - # This is an undocumented feature... - --debug) - debug=yes ;; - --debug-image) - debug_image="`argument "$option" "$@"`"; shift;; - --debug-image=*) - debug_image="`echo "$option" | sed 's/--debug-image=//'`" ;; - - -f | --force) - setup_force="--force" ;; - - -*) - gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 - usage - exit 1 - ;; - *) - if test "x$install_device" != x; then - gettext "More than one install device?" 1>&2 - echo 1>&2 - usage - exit 1 - fi - install_device="${option}" ;; - esac -done - -if [ x$source_directory = x ]; then - if [ x$target = x ]; then - case x"`uname -m`" in - x"powerpc"* | x"ppc"*) - target="powerpc-ieee1275";; - x"sparc"*) - target="sparc64-ieee1275";; - x"mips"*"el") - target="mipsel-loongson";; - x"mips"*) - target="mips-arc";; - x"ia64"*) - target="ia64-efi";; - x"x86_64"* | x"amd64"*) - # On Linux, we need the efivars kernel modules. - # If no EFI is available this module just does nothing - # besides a small hello and if we detect efi we'll load it - # anyway later. So it should be safe to - # try to load it here. - case "$host_os" in - linux*) - modprobe -q efivars 2>/dev/null || true ;; - esac - if [ -d /sys/firmware/efi ]; then - target="x86_64-efi" - else - target=i386-pc - fi - ;; - x"i"?"86"*) - # On Linux, we need the efivars kernel modules. - # If no EFI is available this module just does nothing - # besides a small hello and if we detect efi we'll load it - # anyway later. So it should be safe to - # try to load it here. - case "$host_os" in - linux*) - modprobe -q efivars 2>/dev/null || true ;; - esac - if [ -d /sys/firmware/efi ]; then - target="i386-efi" - elif [ -e /proc/device-tree ]; then - target=i386-pc - for x in /proc/device-tree/*; do - if [ -e "$x" ]; then - target="i386-ieee1275" - fi - done - else - target=i386-pc - fi - ;; - x"arm"*) - target="arm-uboot";; - *) - gettext "Unable to determine your platform. Use --target." ; - echo ;; - esac - fi - source_directory="${libdir}/@PACKAGE@/$target" -fi - -if ! [ -d "$source_directory" ]; then - gettext_printf "%s doesn't exist. Please specify --target or --directory\\n" "$source_directory" - exit 1 -fi - -. "${source_directory}"/modinfo.sh - -if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] ; then - if [ x$disk_module = xunspecified ]; then - disk_module=biosdisk - fi -elif [ "${grub_modinfo_platform}" = "ieee1275" ] || [ "${grub_modinfo_platform}" = "efi" ] || [ "${grub_modinfo_platform}" = "arc" ] || [ "${grub_modinfo_platform}" = "uboot" ] ; then - disk_module= -else - disk_module=native -fi - -if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ]; then - grub_setup="${sbindir}/@grub_bios_setup@" -fi - -if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]; then - grub_setup="${sbindir}/@grub_sparc64_setup@" -fi - -if test "x$install_device" = x && ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \ - || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]); then - gettext "Install device isn't specified." 1>&2 - echo 1>&2 - usage - exit 1 -fi - -if ! ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \ - || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] \ - || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ] \ - || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "mips-arc" ]); then - install_device= -fi - -# If the debugging feature is enabled, print commands. -setup_verbose= -if test x"$debug" = xyes; then - set -x - setup_verbose="--verbose" - efi_quiet= -fi - -if [ -z "$bootdir" ]; then - # Default bootdir if bootdir not initialized. - bootdir="/@bootdirname@" - - if [ -n "$rootdir" ] ; then - # Initialize bootdir if rootdir was initialized. - bootdir="${rootdir}/@bootdirname@" - fi -fi - -grubdir="`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'`" -device_map="${grubdir}/device.map" - - -# Check if GRUB is installed. -if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then - set $grub_setup dummy - if test -f "$1"; then - : - else - # TRANSLATORS: This message is shown when required executable `%s' - # isn't found - gettext_printf "%s: Not found.\n" "$1" 1>&2 - exit 1 - fi -fi - -set "$grub_mkimage" dummy -if test -f "$1"; then - : -else - # TRANSLATORS: This message is shown when required executable `%s' - # isn't found - gettext_printf "%s: Not found.\n" "$1" 1>&2 - exit 1 -fi - -if [ x"$grub_modinfo_platform" = xefi ]; then - # Find the EFI System Partition. - if test -n "$efidir"; then - install_device="`"$grub_probe" --target=device --device-map= "${efidir}"`" - else - if test -d "${bootdir}/efi"; then - install_device="`"$grub_probe" --target=device --device-map= "${bootdir}/efi"`" - # Is it a mount point? - if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then - efidir="${bootdir}/efi" - fi - elif test -d "${bootdir}/EFI"; then - install_device="`"$grub_probe" --target=device --device-map= "${bootdir}/EFI"`" - # Is it a mount point? - if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then - efidir="${bootdir}/EFI" - fi - elif test -n "$rootdir" && test "x$rootdir" != "x/"; then - # The EFI System Partition may have been given directly using - # --root-directory. - install_device="`"$grub_probe" --target=device --device-map= "${rootdir}"`" - # Is it a mount point? - if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${rootdir}/.."`"; then - efidir="${rootdir}" - fi - fi - - if test -n "$efidir"; then - efi_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${efidir}"` - if test "x$efi_fs" = xfat; then :; else - gettext_printf "%s doesn't look like an EFI partition.\n" "${efidir}" 1>&2 - efidir= - fi - fi - fi - - if test -n "$efidir"; then - # The EFI specification requires that an EFI System Partition must - # contain an "EFI" subdirectory, and that OS loaders are stored in - # subdirectories below EFI. Vendors are expected to pick names that do - # not collide with other vendors. To minimise collisions, we use the - # name of our distributor if possible. - efi_distributor="$bootloader_id" - if test $removable = yes; then - # The specification makes stricter requirements of removable - # devices, in order that only one image can be automatically loaded - # from them. The image must always reside under /EFI/BOOT, and it - # must have a specific file name depending on the architecture. - efi_distributor=BOOT - case "$grub_modinfo_target_cpu" in - i386) - efi_file=BOOTIA32.EFI ;; - x86_64) - efi_file=BOOTX64.EFI ;; - # GRUB does not yet support these architectures, but they're defined - # by the specification so we include them here to ease future - # expansion. - ia64) - efi_file=BOOTIA64.EFI ;; - arm) - efi_file=BOOTARM.EFI ;; - esac - else - # It is convenient for each architecture to have a different - # efi_file, so that different versions can be installed in parallel. - case "$grub_modinfo_target_cpu" in - i386) - efi_file=grubia32.efi ;; - x86_64) - efi_file=grubx64.efi ;; - # GRUB does not yet support these architectures, but they're defined - # by the specification so we include them here to ease future - # expansion. - ia64) - efi_file=grubia64.efi ;; - arm) - efi_file=grubarm.efi ;; - *) - efi_file=grub.efi ;; - esac - fi - efidir="$efidir/EFI/$efi_distributor" - mkdir -p "$efidir" || exit 1 - else - # We don't know what's going on. Fall back to traditional - # (non-specification-compliant) behaviour. - efidir="$grubdir" - efi_distributor= - efi_file=grub.efi - fi -fi - -# Create the GRUB directory if it is not present. -mkdir -p "$grubdir" || exit 1 -mkdir -p "$grubdir/${grub_modinfo_target_cpu}-$grub_modinfo_platform" || exit 1 - -# If --recheck is specified, remove the device map, if present. -if test $recheck = yes; then - rm -f "$device_map" -fi - -# Device map file is optional -if test -f "$device_map"; then - # 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 - gettext_printf "The drive %s is defined multiple times in the device map %s\n" "$tmp" "$device_map" 1>&2 - exit 1 - fi -else - device_map= -fi - -# Copy the GRUB images to the GRUB directory. -grub_install_files "${source_directory}" "${grubdir}" "${grub_modinfo_target_cpu}-$grub_modinfo_platform" all - -if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then - for file in "${source_directory}"/*.img "${source_directory}"/efiemu??.o; do - if test -f "$file"; then - cp -f "$file" "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform" || exit 1 - fi - done -fi - -if ! is_path_readable_by_grub "${grubdir}"; then - gettext_printf "Path \`%s' is not readable by GRUB on boot. Installation is impossible. Aborting.\n" "${grubdir}" 1>&2 - exit 1 -fi - -# Write device to a variable so we don't have to traverse /dev every time. -grub_device="`"$grub_probe" --device-map="${device_map}" --target=device "${grubdir}"`" || exit 1 - -if ! test -f "${grubdir}"/grubenv; then - "$grub_editenv" "${grubdir}"/grubenv create -fi - -# Create the core image. First, auto-detect the filesystem module. -fs_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs --device `" -if test "x$fs_module" = x ; then - gettext_printf "Auto-detection of a filesystem of %s failed.\n" "${grub_device}" 1>&2 - gettext "Try with --recheck." 1>&2 - echo 1>&2 - gettext_printf "If the problem persists please report this together with the output of %s to <%s>" "\"$grub_probe --device-map=\"${device_map}\" --target=fs -v ${grubdir}\"" "bug-grub@gnu.org" 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= -for x in `echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=partmap --device 2> /dev/null`; do - case "$x" in - netbsd | openbsd) - partmap_module="$partmap_module part_bsd";; - "") ;; - *) - partmap_module="$partmap_module part_$x";; - esac -done - -# Device abstraction module, if any (lvm, raid). -devabstraction_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=abstraction --device`" - -if [ "x$disk_module" = xata ]; then - disk_module=pata -fi - -if [ "x$disk_module" = xnative ]; then - disk_module="pata ahci ohci" - if [ "x$grub_modinfo_target_cpu" = "xi386" ] || [ "x$grub_modinfo_target_cpu" = "xx86_64" ]; then - disk_module="$disk_module uhci" - fi - disk_module="$disk_module usbms" -fi - -# The order in this list is critical. Be careful when modifying it. -modules="$modules $disk_module" -modules="$modules $fs_module $partmap_module $devabstraction_module" - -relative_grubdir="`"$grub_mkrelpath" "${grubdir}"`" || exit 1 -if [ "x${relative_grubdir}" = "x" ] ; then - relative_grubdir=/ -fi - -prefix_drive= -config_opt_file= - -rm -f "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - -if [ "x${debug_image}" != x ]; then - echo "set debug='${debug_image}'" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" -fi - -if [ "x${devabstraction_module}" = "x" ] ; then - if [ x"${install_device}" != x ]; then - if echo "${install_device}" | grep -qx "(.*)" ; then - install_drive="${install_device}" - else - install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${install_device}"`" || exit 1 - fi - install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`" - fi - grub_drive="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=drive --device`" || exit 1 - - # Strip partition number - grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`" - grub_drive="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`" - - if [ x"${install_device}" = x ] && [ x"${grub_modinfo_target_cpu}-$grub_modinfo_platform" = x"powerpc-ieee1275" ]; then - install_drive="$grub_drive" - fi - - if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$grub_modinfo_platform" != xefi ] && [ "x$grub_modinfo_platform" != xpc ] && [ x"${grub_modinfo_platform}" != x"ieee1275" ]); then - # generic method (used on coreboot and ata mod) - uuid= - if [ x"$force_file_id" != xy ]; then - uuid="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs_uuid --device`" - fi - - if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then - hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`" - elif [ x"$grub_modinfo_platform" = xpc ]; then - hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=bios_hints --device`" - elif [ x"$grub_modinfo_platform" = xefi ]; then - hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=efi_hints --device`" - elif [ x"$grub_modinfo_platform" = xieee1275 ]; then - hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device`" - elif [ x"$grub_modinfo_platform" = xloongson ] || [ x"$grub_modinfo_platform" = xqemu ] || [ x"$grub_modinfo_platform" = xcoreboot ] || [ x"$grub_modinfo_platform" = xmultiboot ] || [ x"$grub_modinfo_platform" = xqemu-mips ]; then - hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`" - else - gettext "No hints available for your platform. Expect reduced performance." 1>&2 - echo 1>&2 - hints= - fi - if [ x"$uuid" != x ]; then - echo "search.fs_uuid ${uuid} root $hints " >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - search_module=search_fs_uuid - else - mkdir -p "${grubdir}/uuid" - file="`mktemp "${grubdir}/uuid/XXXXXXXXXXXXXXXXXXXXXXXXX"`" - relfile="`${grub_mkrelpath} "$file"`" - echo "search.file '${relfile}' root $hints " >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - search_module=search_fs_file - fi - echo 'set prefix=($root)'"$(echo "${relative_grubdir}" | sed "s,\\([ \"'\\\\]\\),\\\\\\1,g")" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - modules="$modules $search_module" - else - # we need to hardcode the partition number in the core image's prefix. - if [ x"$grub_partition" = x ]; then - prefix_drive="()" - else - # Comma is already there - prefix_drive="($grub_partition)" - fi - fi -else - if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then - for uuid in "`echo "${grub_device}" | xargs "${grub_probe}" --target=cryptodisk_uuid --device`"; do - echo "cryptomount -u $uuid" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - done - config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg" - fi - - prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1 -fi - -case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in - sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; - mipsel-loongson) mkimage_target=mipsel-loongson-elf ;; - mips-qemu_mips | mipsel-qemu_mips) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}"-elf ;; - *) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}" ;; -esac - -case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in - i386-efi | x86_64-efi | ia64-efi) imgext=efi ;; - mipsel-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \ - | powerpc-ieee1275 | mips-qemu_mips | mipsel-qemu_mips) imgext=elf ;; - *) imgext=img ;; -esac - -if [ x"$config_opt_file" = x ]; then - "$grub_mkimage" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1 -else - "$grub_mkimage" -c "${config_opt_file}" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1 -fi - -# Backward-compatibility kludges -if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "mipsel-loongson" ]; then - cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${bootdir}"/grub.elf -elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ]; then - cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${grubdir}/grub" -elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-efi" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "x86_64-efi" ]; then - - if [ x"$config_opt_file" = x ]; then - "$grub_mkimage" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1 - else - "$grub_mkimage" -c "${config_opt_file}" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1 - fi -fi - - -# Perform the grub_modinfo_platform-dependent install -if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then - # Now perform the installation. - "$grub_setup" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform" \ - --device-map="${device_map}" "${install_device}" || exit 1 -elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ]; then - - # If a install device is defined, copy the core.elf to PReP partition. - if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ] && [ -n "${install_device}" ]; then - - if [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t msdos_parttype)" != "41" ] \ - && [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t gpt_parttype)" != "9e1a2d38-c612-4316-aa26-8b49521e5a8b" ]; then - gettext "The chosen partition is not a PReP partition." 1>&2 - echo 1>&2 - exit 1 - fi - - if [ "$(file -s -b -L "${install_device}" | awk '{ print $1 }')" = ELF ] || [ x$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t zero_check) = xtrue ]; then - dd if="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" of="${install_device}" status=noxfer || { - gettext "Failed to copy Grub to the PReP partition." 1>&2 - echo 1>&2 - exit 1 - } - else - gettext "The PReP partition is not empty. If you are sure you want to use it, run dd to clear it:" 1>&2 - echo 1>&2 - echo " dd if=/dev/zero of=${install_device}" - exit 1 - fi - fi - - if [ x"$update_nvram" = xyes ]; then - ofpathname="`which ofpathname`" - nvsetenv="`which nvsetenv`" - set "$ofpathname" dummy - if test -f "$1"; then - : - else - # TRANSLATORS: This message is shown when required executable `%s' - # isn't found - gettext_printf "%s: Not found.\n" "$1" 1>&2 - exit 1 - fi - set "$nvsetenv" dummy - if test -f "$1"; then - : - else - # TRANSLATORS: This message is shown when required executable `%s' - # isn't found - gettext_printf "%s: Not found.\n" "$1" 1>&2 - exit 1 - fi - if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" != "powerpc-ieee1275" ] \ - || [ -z "${install_device}" ]; then - # Get the Open Firmware device tree path translation. - dev="`echo $grub_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`" - partno="`echo $grub_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'`" - ofpath="`$ofpathname $dev`" || { - # TRANSLATORS: "device tree path" is the name of the device - # for IEEE1275 - gettext_printf "Couldn't find IEEE1275 device tree path for %s.\nYou will have to set \`boot-device' variable manually.\n" "$dev" 1>&2 - exit 1 - } - - # Point boot-device at the new grub install - boot_device="$ofpath:$partno,"`"$grub_mkrelpath" "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" | sed 's,/,\\\\,g'` - - else - - dev="`echo "${install_device}" | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`" - boot_device="`$ofpathname "$dev"`" || { - # TRANSLATORS: "device tree path" is the name of the device - # for IEEE1275 - gettext_printf "Couldn't find IEEE1275 device tree path for %s.\nYou will have to set \`boot-device' variable manually.\n" "$dev" 1>&2 - exit 1 - } - fi - - "$nvsetenv" boot-device "$boot_device" || { - # TRANSLATORS: The %s will be replaced by an external program name. - gettext_printf "\`%s' failed.\n" "$nvsetenv" 1>&2 - gettext "You will have to set \`boot-device' variable manually. At the IEEE1275 prompt, type:" 1>&2 - echo 1>&2 - echo " setenv boot-device $boot_device" 1>&2 - exit 1 - } - fi -elif [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = xmips-arc ]; then - dvhtool -d "${install_device}" --unix-to-vh "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" grub - gettext "You will have to set \`SystemPartition' and \`OSLoader' manually." 1>&2 - echo 1>&2 -elif [ x"$grub_modinfo_platform" = xefi ]; then - cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${efidir}/${efi_file}" - # For old macs. Suggested by Peter Jones. - if [ x$grub_modinfo_target_cpu = xi386 ]; then - cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${efidir}/boot.efi" - fi - - # Try to make this image bootable using the EFI Boot Manager, if available. - if test "$removable" = no; then - - efibootmgr="`which efibootmgr`" || { - # TRANSLATORS: This message is shown when required executable `%s' - # isn't found - gettext_printf "%s: Not found.\n" "efibootmgr" 1>&2 - exit 1 - } - - test -n "$efi_distributor" || { - gettext "EFI distributor id isn't specified." 1>&2 - echo 1>&2 - exit 1 - } - - # On Linux, we need the efivars kernel modules. - case "$host_os" in - linux*) - modprobe -q efivars 2>/dev/null || true ;; - esac - - # Delete old entries from the same distributor. - for bootnum in `efibootmgr | grep '^Boot[0-9]' | \ - fgrep -i " $efi_distributor" | cut -b5-8`; do - efibootmgr $efi_quiet -b "$bootnum" -B - done - - # Add a new entry for the image we just created. efibootmgr needs to be - # given the disk device and partition number separately, so we have to - # fiddle about with grub-probe to get hold of this reasonably reliably. - # Use fresh device map text to avoid any problems with stale data, since - # all we need here is a one-to-one mapping. - efidir_drive="$("$grub_probe" --target=drive --device-map= "$efidir")" - efidir_disk="$("$grub_probe" --target=disk --device-map= "$efidir")" - if test -z "$efidir_drive" || test -z "$efidir_disk"; then - gettext_printf "Can't find GRUB drive for %s; unable to create EFI Boot Manager entry.\n" "$efidir" >&2 - else - efidir_part="$(echo "$efidir_drive" | sed 's/^([^,]*,[^0-9]*//; s/[^0-9].*//')" - efibootmgr $efi_quiet -c -d "$efidir_disk" -p "$efidir_part" -w \ - -L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file" - fi - fi -else - gettext "WARNING: no platform-specific install was performed" 1>&2 - echo 1>&2 -fi - -gettext "Installation finished. No error reported." 1>&2 -echo 1>&2 - -# Bye. -exit 0 diff --git a/util/grub-install_header b/util/grub-install_header deleted file mode 100644 index 2759ae89e..000000000 --- a/util/grub-install_header +++ /dev/null @@ -1,263 +0,0 @@ -#! /bin/sh -set -e - -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 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 . - -prefix="@prefix@" -exec_prefix="@exec_prefix@" -datarootdir="@datarootdir@" -bindir="@bindir@" - -libdir="@libdir@" -PACKAGE_NAME=@PACKAGE_NAME@ -PACKAGE_TARNAME=@PACKAGE_TARNAME@ -PACKAGE_VERSION=@PACKAGE_VERSION@ -datadir="@datadir@" -if [ "x$pkgdatadir" = x ]; then - pkgdatadir="${datadir}/@PACKAGE@" -fi -localedir="@datadir@/locale" - -self=`basename $0` - -export TEXTDOMAIN=@PACKAGE@ -export TEXTDOMAINDIR="@localedir@" - -. "${pkgdatadir}/grub-mkconfig_lib" - -modules= - -pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst \ -handler.lst video.lst crypto.lst terminal.lst" - -grub_mkimage="${bindir}/@grub_mkimage@" - -grub_compress_file () { - if [ -f "$1" ] ; then - if [ "$compressor" != "" ] ; then - "$compressor" $compressor_opts "$1" > "$2" - else - cp -f "$1" "$2" - fi - else - gettext_printf "Skipping file \`%s': not a plain file\n" "$1" 1>&2 - fi -} - -grub_install_files () { - grub_install_files_source_directory="$1" - grub_install_files_target_directory="$2" - grub_install_files_platform="$3" - - mkdir -p "${grub_install_files_target_directory}"/"${grub_install_files_platform}" - - for file in "${grub_install_files_target_directory}"/*.mod \ -"${grub_install_files_target_directory}"/*.lst \ -"${grub_install_files_target_directory}"/*.img \ -"${grub_install_files_target_directory}"/efiemu??.o \ -"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.mod \ -"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.lst \ -"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.img \ -"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/efiemu??.o; - do - if test -f "$file" && [ "`basename $file`" != menu.lst ]; then - rm -f "$file" || exit 1 - fi - done - - if [ x"$install_modules" = xall ]; then - for file in "${grub_install_files_source_directory}/"*.mod; do - grub_compress_file "$file" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$(basename "$file")" - done - else - modules1= - modules2="$install_modules" - while [ x"$modules2" != x ]; do - modules3= - for x in $modules2; do - modules3="$modules3 $(grep "^$x:" "${grub_install_files_source_directory}/moddep.lst" | sed 's,^[^:]*:,,')" - done - modules1="$modules1 $modules2" - modules2="$modules3" - done - for file in $(echo "$modules1" | sed 's, ,\n,g' |sort -u); do - grub_compress_file "${grub_install_files_source_directory}/$file.mod" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$file.mod" - done - fi - - for file in ${pkglib_DATA} efiemu32.o efiemu64.o; do - if test -f "${grub_install_files_source_directory}/${file}"; then - grub_compress_file "${grub_install_files_source_directory}/${file}" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/${file}" - fi - done - - # Copy gettext files - mkdir -p "${grub_install_files_target_directory}"/locale - - for file in "${grub_install_files_target_directory}"/locale/*.mo; do - if test -f "$file"; then - rm -f "$file" || exit 1 - fi - done - - if [ x"$install_locales" = xall ]; then - for file in "${grub_install_files_source_directory}"/po/*.mo; do - if test -f "$file"; then - grub_compress_file "$file" "${grub_install_files_target_directory}"/locale/"$(basename "$file")" - fi - done - for dir in "${localedir}"/*; do - if test -f "$dir/LC_MESSAGES/@PACKAGE@.mo" && ! test -f "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"; then - grub_compress_file "$dir/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo" - fi - done - else - for locale in $install_locales; do - if test -f "${grub_install_files_source_directory}"/po/$locale.mo; then - grub_compress_file "${grub_install_files_source_directory}"/po/locale.mo "${grub_install_files_target_directory}"/locale/$locale.mo - elif test -f "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo"; then - grub_compress_file "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/$locale.mo - fi - done - fi - for theme in ${install_themes} ; do - if test -f "${pkgdatadir}"/themes/"${theme}"/theme.txt; then - mkdir -p "${grub_install_files_target_directory}"/themes/"${theme}" - for file in "${pkgdatadir}"/themes/"${theme}"/*; do - grub_compress_file "$file" "${grub_install_files_target_directory}"/themes/"${theme}"/"$(basename "$file")" - done - fi - done - - for font in ${install_fonts} ; do - if test -f "${pkgdatadir}"/"$font".pf2; then - mkdir -p "${grub_install_files_target_directory}"/fonts - grub_compress_file "${pkgdatadir}"/"$font".pf2 "${grub_install_files_target_directory}"/fonts/"$font".pf2 - fi - done -} - -grub_print_install_files_help () { - print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")" - print_option_help "--install-modules=$(gettext "MODULES")" "$(gettext "install only MODULES and their dependencies [default=all]")" - print_option_help "--themes=THEMES" "$(gettext_printf "install THEMES [default=%s]" "starfield")" - print_option_help "--fonts=FONTS" "$(gettext_printf "install FONTS [default=%s]" "unicode")" - print_option_help "--locales=LOCALES" "$(gettext_printf "install only LOCALES [default=all]")" - print_option_help "--compress[=no,xz,gz,lzo]" "$(gettext "compress GRUB files [optional]")" - # TRANSLATORS: platform here isn't identifier. It can be translated. - dir_msg="$(gettext_printf "use images and modules under DIR [default=%s/]" "${libdir}/@PACKAGE@")" - print_option_help "-d, --directory=$(gettext "DIR")" "$dir_msg" - print_option_help "--grub-mkimage=$(gettext "FILE")" "$(gettext "use FILE as grub-mkimage")" - print_option_help "-v, --version" "$(gettext "print the version information and exit")" -} - -install_modules=all -install_themes=starfield -install_fonts=unicode -install_locales=all -compress=no -grub_decompression_module="" -compressor="" -compressor_opts="" -source_directory="" - -argument () { - opt=$1 - shift - - if test $# -eq 0; then - gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2 - exit 1 - fi - echo $1 -} - -grub_parse_compress () { - compress="$1" - case x"$compress" in - xno) ;; - xgz) - compressor=`which gzip || true` - grub_decompression_module="gzio" - compressor_opts="--best --stdout";; - xxz) - compressor=`which xz || true` - grub_decompression_module="xzio gcry_crc" - compressor_opts="--lzma2=dict=128KiB --check=none --stdout";; - xlzo) - compressor=`which lzop || true` - grub_decompression_module="lzopio adler32 gcry_crc" - compressor_opts="-9 -c";; - *) - gettext_printf "Unrecognized compression \`%s'\n" "$compress" 1>&2 - usage - exit 1 - esac -} - -grub_process_install_options () { - option=$1 - shift - - grub_process_install_options_consumed=0 - - case "$option" in - --install-modules) - install_modules=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; - --install-modules=*) - install_modules=`echo "$option" | sed 's/--install-modules=//'`; grub_process_install_options_consumed=1; return ;; - --themes) - install_themes=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; - --themes=*) - install_themes=`echo "$option" | sed 's/--themes=//'`; grub_process_install_options_consumed=1; return ;; - --fonts) - install_fonts=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; - --fonts=*) - install_fonts=`echo "$option" | sed 's/--fonts=//'`; grub_process_install_options_consumed=1; return ;; - --locales) - install_locales=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; - --locales=*) - install_locales=`echo "$option" | sed 's/--locales=//'`; grub_process_install_options_consumed=1; return ;; - --compress) - grub_parse_compress `argument $option "$@"`; grub_process_install_options_consumed=2; return ;; - --compress=*) - grub_parse_compress `echo "${option}" | sed 's/--compress=//'`; grub_process_install_options_consumed=1; return ;; - --directory | -d) - source_directory=`argument $option "$@"`; grub_process_install_options_consumed=2 ;; - --directory=*) - source_directory=`echo "$option" | sed 's/--directory=//'` grub_process_install_options_consumed=1;; - - # For backwards compatibility - --override-directory) - source_directory=`argument $option "$@"`; grub_process_install_options_consumed=2 ;; - --override-directory=*) - source_directory=`echo "$option" | sed 's/--override-directory=//'` grub_process_install_options_consumed=1;; - - --grub-mkimage) - grub_mkimage=`argument $option "$@"`; grub_process_install_options_consumed=2 ;; - --grub-mkimage=*) - grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'`;grub_process_install_options_consumed=1 ;; - --modules) - modules=`argument $option "$@"`; grub_process_install_options_consumed=2;; - --modules=*) - modules=`echo "$option" | sed 's/--modules=//'` grub_process_install_options_consumed=1;; - -v | --version) - echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" - exit 0 ;; - esac -} - -export grub_decompression_module diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 6e1e424db..33cce36ad 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -45,6 +45,7 @@ #include #include #include +#include #define _GNU_SOURCE 1 #include @@ -83,7 +84,7 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused))) switch (key) { case 'd': - return xasprintf (text, GRUB_PKGLIBDIR); + return xasprintf (text, grub_util_get_pkglibdir ()); case 'p': return xasprintf (text, DEFAULT_DIRECTORY); case 'O': @@ -268,10 +269,12 @@ main (int argc, char *argv[]) if (!arguments.dir) { const char *dn = grub_util_get_target_dirname (arguments.image_target); - arguments.dir = xmalloc (sizeof (GRUB_PKGLIBDIR) + grub_strlen (dn) + 1); - memcpy (arguments.dir, GRUB_PKGLIBDIR, sizeof (GRUB_PKGLIBDIR) - 1); - *(arguments.dir + sizeof (GRUB_PKGLIBDIR) - 1) = '/'; - strcpy (arguments.dir + sizeof (GRUB_PKGLIBDIR), dn); + const char *pkglibdir = grub_util_get_pkglibdir (); + char *ptr; + arguments.dir = xmalloc (grub_strlen (pkglibdir) + grub_strlen (dn) + 2); + ptr = grub_stpcpy (arguments.dir, pkglibdir); + *ptr++ = '/'; + strcpy (ptr, dn); } grub_install_generate_image (arguments.dir, diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c new file mode 100644 index 000000000..20130d3cf --- /dev/null +++ b/util/grub-mknetdir.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013 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 + +static char *rootdir = NULL, *subdir = NULL; +static char *debug_image = NULL; + +enum + { + OPTION_NET_DIRECTORY = 0x301, + OPTION_SUBDIR, + OPTION_DEBUG, + OPTION_DEBUG_IMAGE + }; + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"net-directory", OPTION_NET_DIRECTORY, N_("DIR"), + 0, N_("root directory of TFTP server"), 2}, + {"subdir", OPTION_SUBDIR, N_("DIR"), + 0, N_("relative subdirectory on network server"), 2}, + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, "DEBUG", OPTION_HIDDEN, 0, 2}, + {0, 0, 0, 0, 0, 0} +}; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_NET_DIRECTORY: + free (rootdir); + rootdir = xstrdup (arg); + return 0; + case OPTION_SUBDIR: + free (subdir); + subdir = xstrdup (arg); + return 0; + /* This is an undocumented feature... */ + case OPTION_DEBUG: + verbosity++; + return 0; + case OPTION_DEBUG_IMAGE: + free (debug_image); + debug_image = xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + default: + return ARGP_ERR_UNKNOWN; + } +} + + +struct argp argp = { + options, argp_parser, N_("[OPTION]"), + "\v"N_("copies GRUB images into net_directory/subdir/target_cpu-platform."), + NULL, grub_install_help_filter, NULL +}; + +static char *base; + +static const struct +{ + const char *mkimage_target; + const char *netmodule; + const char *ext; +} targets[GRUB_INSTALL_PLATFORM_MAX] = + { + [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" }, + [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" }, + [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" }, + [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" }, + [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" } + }; + +static void +process_input_dir (const char *input_dir, enum grub_install_plat platform) +{ + char *platsub = grub_install_get_platform_name (platform); + char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub); + char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg"); + char *prefix; + char *output; + char *grub_cfg; + FILE *cfg; + + grub_install_copy_files (input_dir, base, platform); + grub_util_unlink (load_cfg); + + if (debug_image) + { + FILE *f = grub_util_fopen (load_cfg, "wb"); + if (!f) + grub_util_error (_("cannot open `%s': %s"), load_cfg, + strerror (errno)); + fprintf (f, "set debug='%s'\n", debug_image); + fclose (f); + } + else + { + free (load_cfg); + load_cfg = 0; + } + + prefix = xasprintf ("/%s", subdir); + if (!targets[platform].mkimage_target) + grub_util_error ("unsupported platform %s\n", platsub); + + grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg"); + cfg = grub_util_fopen (grub_cfg, "wb"); + if (!cfg) + grub_util_error (_("cannot open `%s': %s"), grub_cfg, + strerror (errno)); + fprintf (cfg, "source %s/grub.cfg", subdir); + fclose (cfg); + + grub_install_push_module (targets[platform].netmodule); + + output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext); + grub_install_make_image_wrap (input_dir, prefix, output, + 0, load_cfg, + targets[platform].mkimage_target, 0, + GRUB_COMPRESSION_AUTO); + grub_install_pop_module (); + + /* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */ + printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"), + platsub, output); + + free (platsub); + free (output); + free (prefix); + free (grub_cfg); + free (grubdir); +} + + +int +main (int argc, char *argv[]) +{ + const char *pkgdatadir = grub_util_get_pkgdatadir (); + + grub_util_host_init (&argc, &argv); + rootdir = xstrdup ("/srv/tftp"); + + subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + base = grub_util_path_concat (2, rootdir, subdir); + /* Create the GRUB directory if it is not present. */ + + grub_install_mkdir_p (base); + + grub_install_push_module ("tftp"); + + if (!grub_install_source_directory) + { + enum grub_install_plat plat; + + for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) + if (targets[plat].mkimage_target) + { + char *platdir = grub_util_path_concat (2, pkgdatadir, + grub_install_get_platform_name (plat)); + + if (!grub_util_is_directory (platdir)) + { + free (platdir); + continue; + } + process_input_dir (platdir, plat); + } + } + else + { + enum grub_install_plat plat; + plat = grub_install_get_target (grub_install_source_directory); + process_input_dir (grub_install_source_directory, plat); + } + return 0; +} diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in deleted file mode 100644 index b7b59da41..000000000 --- a/util/grub-mknetdir.in +++ /dev/null @@ -1,183 +0,0 @@ -# Install GRUB on your drive. -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 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. -host_os=@host_os@ - -rootdir=/srv/tftp -modules= - -no_floppy= -recheck=no -debug=no -debug_image= -subdir="`echo '/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"`" -pc_dir="${libdir}/@PACKAGE@/i386-pc" -ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275" -sparc_dir="${libdir}/@PACKAGE@/sparc64-ieee1275" -i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275" -efi32_dir="${libdir}/@PACKAGE@/i386-efi" -efi64_dir="${libdir}/@PACKAGE@/x86_64-efi" -itanium_dir="${libdir}/@PACKAGE@/ia64-efi" - -# Usage: usage -# Print the usage. -usage () { - gettext_printf "Usage: %s [OPTION]\n" "$self" - echo - print_option_help "-h, --help" "$(gettext "print this message and exit")" - grub_print_install_files_help - print_option_help "--net-directory=$(gettext "DIR")" "$(gettext "root directory of TFTP server")" - print_option_help "--subdir=$(gettext "DIR")" "$(gettext "relative subdirectory on network server")" - echo - gettext_printf "%s copies GRUB images into net_directory/subdir/target_cpu-platform\n" "$self" - echo - gettext "Report bugs to ."; echo -} - -# Check the arguments. -while test $# -gt 0 -do - grub_process_install_options "$@" - case "$grub_process_install_options_consumed" in - 1) shift; continue;; - 2) shift; shift; continue;; - esac - - option=$1 - shift - - case "$option" in - -h | --help) - usage - exit 0 ;; - - --net-directory) - rootdir=`argument $option "$@"`; shift;; - --net-directory=*) - rootdir=`echo "$option" | sed 's/--net-directory=//'` ;; - - --subdir) - subdir=`argument $option "$@"`; shift;; - --subdir=*) - subdir=`echo "$option" | sed 's/--subdir=//'` ;; - - # This is an undocumented feature... - --debug) - debug=yes ;; - --debug-image) - debug_image=`argument $option "$@"`; shift;; - --debug-image=*) - debug_image=`echo "$option" | sed 's/--debug-image=//'` ;; - - -*) - gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 - usage - exit 1 - ;; - *) - gettext_printf "Unknown extra argument \`%s'." "$option" 1>&2 - echo 1>&2 - usage - exit 1 - ;; - esac -done - -set $grub_mkimage dummy -if test -f "$1"; then - : -else - gettext_printf "%s: Not found.\n" "$1" 1>&2 - exit 1 -fi - -# Create the GRUB directory if it is not present. -mkdir -p "${rootdir}/${subdir}" || exit 1 - -process_input_dir () -{ - input_dir="$1" - platform="$2" - grubdir="${rootdir}/${subdir}/${platform}" - config_opt= - - grub_install_files "${input_dir}" "${rootdir}/${subdir}" "${platform}" - - rm -f "${grubdir}"/load.cfg - - if [ "x${debug_image}" != x ]; then - echo "set debug='${debug_image}'" >> ${grubdir}/load.cfg - config_opt="-c ${grubdir}/load.cfg " - fi - - prefix="/${subdir}"; - case "${platform}" in - i386-pc) mkimage_target=i386-pc-pxe; - netmodules="pxe"; - ext=0 ;; - sparc64-ieee1275) mkimage_target=sparc64-ieee1275-aout; - netmodules="ofnet"; - ext=img ;; - *-ieee1275) mkimage_target="${platform}"; - netmodules="ofnet"; - ext=elf ;; - *-efi) mkimage_target="${platform}"; - netmodules="efinet"; - ext=efi ;; - *) gettext_printf "Unsupported platform %s\n" ${platform}; - exit 1;; - esac - - cat << EOF > ${grubdir}/grub.cfg -source ${subdir}/grub.cfg -EOF - - "$grub_mkimage" ${config_opt} -d "${input_dir}" -O ${mkimage_target} "--output=${grubdir}/core.$ext" "--prefix=$prefix" $modules $grub_decompression_module $netmodules tftp || exit 1 - # TRANSLATORS: First %s is replaced by platform name. Second one by filename. - gettext_printf "Netboot directory for %s created. Configure your DHCP server to point to %s\n" "${platform}" "${subdir}/${platform}/core.$ext" -} - -if [ "${source_directory}" = "" ] ; then - if test -e "${pc_dir}" ; then - process_input_dir "${pc_dir}" i386-pc - fi - if test -e "${ppc_dir}" ; then - process_input_dir "${ppc_dir}" powerpc-ieee1275 - fi - if test -e "${sparc_dir}" ; then - process_input_dir ${sparc_dir} sparc64-ieee1275 - fi - if test -e "${i386_ieee1275_dir}" ; then - process_input_dir "${i386_ieee1275_dir}" i386-ieee1275 - fi - if test -e "${efi32_dir}" ; then - process_input_dir "${efi32_dir}" i386-efi - fi - if test -e "${efi64_dir}" ; then - process_input_dir "${efi64_dir}" x86_64-efi - fi - if test -e "${itanium_dir}" ; then - process_input_dir "${itanium_dir}" ia64-efi - fi -else - . "${source_directory}"/modinfo.sh - process_input_dir "${source_directory}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} -fi - - -# Bye. -exit 0 diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c new file mode 100644 index 000000000..0b8c39bcb --- /dev/null +++ b/util/grub-mkrescue.c @@ -0,0 +1,827 @@ +/* + * Make GRUB rescue image + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 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 + +static char *source_dirs[GRUB_INSTALL_PLATFORM_MAX]; +static char *rom_directory; +static char *label_font; +static char *label_color; +static char *label_bgcolor; +static char *product_name; +static char *product_version; +static int xorriso_tail_argc; +static int xorriso_tail_arg_alloc; +static char **xorriso_tail_argv; +static char *output_image; +static char *xorriso; +static char *boot_grub; +static int xorriso_argc; +static int xorriso_arg_alloc; +static char **xorriso_argv; +static char *iso_uuid; +static char *iso9660_dir; + +static void +xorriso_push (const char *val) +{ + if (xorriso_arg_alloc <= xorriso_argc + 1) + { + xorriso_arg_alloc = 2 * (4 + xorriso_argc); + xorriso_argv = xrealloc (xorriso_argv, + sizeof (xorriso_argv[0]) + * xorriso_arg_alloc); + } + xorriso_argv[xorriso_argc++] = xstrdup (val); +} + +static void +xorriso_link (const char *from, const char *to) +{ + char *tof = grub_util_path_concat (2, iso9660_dir, to); + char *val = xasprintf ("%s=%s", from, tof); + xorriso_push (val); + free (val); + free (tof); +} + +enum + { + OPTION_OUTPUT = 'o', + OPTION_ROM_DIRECTORY = 0x301, + OPTION_XORRISO, + OPTION_GLUE_EFI, + OPTION_RENDER_LABEL, + OPTION_LABEL_FONT, + OPTION_LABEL_COLOR, + OPTION_LABEL_BGCOLOR, + OPTION_PRODUCT_NAME, + OPTION_PRODUCT_VERSION, + OPTION_SPARC_BOOT, + OPTION_ARCS_BOOT + }; + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"output", 'o', N_("FILE"), + 0, N_("save output in FILE [required]"), 2}, + {"rom-directory", OPTION_ROM_DIRECTORY, N_("DIR"), + 0, N_("save ROM images in DIR [optional]"), 2}, + {"xorriso", OPTION_XORRISO, N_("FILE"), + /* TRANSLATORS: xorriso is a program for creating ISOs and burning CDs. */ + 0, N_("use FILE as xorriso [optional]"), 2}, + {"grub-glue-efi", OPTION_GLUE_EFI, N_("FILE"), OPTION_HIDDEN, 0, 2}, + {"grub-render-label", OPTION_RENDER_LABEL, N_("FILE"), OPTION_HIDDEN, 0, 2}, + {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, + {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, + {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, + {"product-name", OPTION_PRODUCT_NAME, N_("STRING"), 0, N_("use STRING as product name"), 2}, + {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2}, + {"sparc-boot", OPTION_SPARC_BOOT, 0, 0, N_("enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc"), 2}, + {"arcs-boot", OPTION_ARCS_BOOT, 0, 0, N_("enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc"), 2}, + {0, 0, 0, 0, 0, 0} +}; + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case ARGP_KEY_HELP_POST_DOC: + return xasprintf (text, "xorriso -as mkisofs -help"); + default: + return grub_install_help_filter (key, text, input); + } +} + +enum { + SYS_AREA_AUTO, + SYS_AREA_COMMON, + SYS_AREA_SPARC, + SYS_AREA_ARCS +} system_area = SYS_AREA_AUTO; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_OUTPUT: + free (output_image); + output_image = xstrdup (arg); + return 0; + case OPTION_ROM_DIRECTORY: + free (rom_directory); + rom_directory = xstrdup (arg); + return 0; + + /* + FIXME: + # Intentionally undocumented + --grub-mkimage-extra) + mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;; + --grub-mkimage-extra=*) + mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;; + */ + case OPTION_SPARC_BOOT: + system_area = SYS_AREA_SPARC; + return 0; + case OPTION_ARCS_BOOT: + system_area = SYS_AREA_ARCS; + return 0; + case OPTION_PRODUCT_NAME: + free (product_name); + product_name = xstrdup (arg); + return 0; + case OPTION_PRODUCT_VERSION: + free (product_version); + product_version = xstrdup (arg); + return 0; + /* Accept and ignore for compatibility. */ + case OPTION_GLUE_EFI: + case OPTION_RENDER_LABEL: + return 0; + case OPTION_LABEL_FONT: + free (label_font); + label_font = xstrdup (arg); + return 0; + + case OPTION_LABEL_COLOR: + free (label_color); + label_color = xstrdup (arg); + return 0; + + case OPTION_LABEL_BGCOLOR: + free (label_bgcolor); + label_bgcolor = xstrdup (arg); + return 0; + + case OPTION_XORRISO: + free (xorriso); + xorriso = xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + if (xorriso_tail_arg_alloc <= xorriso_tail_argc) + { + xorriso_tail_arg_alloc = 2 * (4 + xorriso_tail_argc); + xorriso_tail_argv = xrealloc (xorriso_tail_argv, + sizeof (xorriso_tail_argv[0]) + * xorriso_tail_arg_alloc); + } + xorriso_tail_argv[xorriso_tail_argc++] = xstrdup (arg); + return 0; + default: + return ARGP_ERR_UNKNOWN; + } +} + +struct argp argp = { + options, argp_parser, N_("[OPTION] SOURCE..."), + /* TRANSLATORS: it generates one single image which is bootable through any method. */ + N_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image.")"\v" + N_("Generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of `%s'.\n\n" + "Option -- switches to native xorriso command mode.\n\n" + "Mail xorriso support requests to ."), + NULL, help_filter, NULL +}; + +static void +write_part (FILE *f, const char *srcdir) +{ + FILE *in; + char *inname = grub_util_path_concat (2, srcdir, "partmap.lst"); + char buf[260]; + in = grub_util_fopen (inname, "rb"); + if (!in) + return; + while (fgets (buf, 256, in)) + { + char *ptr; + for (ptr = buf + strlen (buf) - 1; + ptr >= buf && (*ptr == '\n' || *ptr == '\r'); + ptr--); + ptr[1] = '\0'; + fprintf (f, "insmod %s\n", buf); + } + fclose (in); +} + +static void +make_image_abs (enum grub_install_plat plat, + const char *mkimage_target, + const char *output, + grub_compression_t compress) +{ + char *load_cfg; + FILE *load_cfg_f; + + if (!source_dirs[plat]) + return; + + grub_util_info (N_("enabling %s support ..."), + mkimage_target); + + load_cfg = grub_util_make_temporary_file (); + + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid); + fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n"); + + write_part (load_cfg_f, source_dirs[plat]); + fclose (load_cfg_f); + + grub_install_push_module ("search"); + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output, + 0, load_cfg, + mkimage_target, 0, + compress); + grub_install_pop_module (); + grub_install_pop_module (); + grub_util_unlink (load_cfg); +} + +static void +make_image (enum grub_install_plat plat, + const char *mkimage_target, + const char *output_sub, + grub_compression_t compress) +{ + char *out = grub_util_path_concat (2, boot_grub, output_sub); + make_image_abs (plat, mkimage_target, + out, GRUB_COMPRESSION_AUTO); + free (out); +} + +static void +make_image_fwdisk_abs (enum grub_install_plat plat, + const char *mkimage_target, + const char *output) +{ + if (!source_dirs[plat]) + return; + + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output, + 0, 0, mkimage_target, 0, + GRUB_COMPRESSION_AUTO); + grub_install_pop_module (); +} + +static int +check_xorriso (const char *val) +{ + const char *argv[5]; + int fd; + pid_t pid; + FILE *mdadm; + char *buf = NULL; + size_t len = 0; + int ret = 0; + + argv[0] = xorriso; + argv[1] = "-as"; + argv[2] = "mkisofs"; + argv[3] = "-help"; + argv[4] = NULL; + + pid = grub_util_exec_pipe_stderr (argv, &fd); + + if (!pid) + return 0; + + /* Parent. Read mdadm's output. */ + mdadm = fdopen (fd, "r"); + if (! mdadm) + return 0; + + while (getline (&buf, &len, mdadm) > 0) + { + if (grub_strstr (buf, val)) + ret = 1; + } + + close (fd); + waitpid (pid, NULL, 0); + free (buf); + return ret; +} + +static void +make_image_fwdisk (enum grub_install_plat plat, + const char *mkimage_target, + const char *output_sub) +{ + char *out = grub_util_path_concat (2, boot_grub, output_sub); + make_image_fwdisk_abs (plat, mkimage_target, out); + free (out); +} + +int +main (int argc, char *argv[]) +{ + char *romdir; + char *sysarea_img = NULL; + const char *pkgdatadir; + + grub_util_host_init (&argc, &argv); + + pkgdatadir = grub_util_get_pkgdatadir (); + + product_name = xstrdup (PACKAGE_NAME); + product_version = xstrdup (PACKAGE_VERSION); + xorriso = xstrdup ("xorriso"); + label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (!output_image) + grub_util_error ("%s", _("output file must be specified")); + + xorriso_push (xorriso); + xorriso_push ("-as"); + xorriso_push ("mkisofs"); + xorriso_push ("-graft-points"); + + iso9660_dir = grub_util_make_temporary_dir (); + grub_util_info ("temporaray iso9660 dir is `%s'", + iso9660_dir); + boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub"); + grub_install_mkdir_p (boot_grub); + romdir = grub_util_path_concat (2, boot_grub, "roms"); + grub_util_mkdir (romdir); + + if (!grub_install_source_directory) + { + enum grub_install_plat plat; + + for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) + { + char *platdir = grub_util_path_concat (2, pkgdatadir, + grub_install_get_platform_name (plat)); + + if (!grub_util_is_directory (platdir)) + { + free (platdir); + continue; + } + source_dirs[plat] = platdir; + grub_install_copy_files (platdir, + boot_grub, plat); + } + } + else + { + enum grub_install_plat plat; + plat = grub_install_get_target (grub_install_source_directory); + grub_install_copy_files (grub_install_source_directory, + boot_grub, plat); + source_dirs[plat] = xstrdup (grub_install_source_directory); + } + if (system_area == SYS_AREA_AUTO || grub_install_source_directory) + { + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC] + || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] + || source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + system_area = SYS_AREA_COMMON; + else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]) + system_area = SYS_AREA_SPARC; + else if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) + system_area = SYS_AREA_ARCS; + } + + /* obtain date-based UUID. */ + { + time_t tim; + struct tm *tmm; + tim = time (NULL); + tmm = gmtime (&tim); + iso_uuid = xmalloc (55); + grub_snprintf (iso_uuid, 50, + "%04d-%02d-%02d-%02d-%02d-%02d-00", + tmm->tm_year + 1900, + tmm->tm_mon + 1, + tmm->tm_mday, + tmm->tm_hour, + tmm->tm_min, + tmm->tm_sec); + } + { + char *uuid_out = xmalloc (strlen (iso_uuid) + 1 + 40); + char *optr; + const char *iptr; + optr = grub_stpcpy (uuid_out, "--modification-date="); + for (iptr = iso_uuid; *iptr; iptr++) + if (*iptr != '-') + *optr++ = *iptr; + *optr = '\0'; + xorriso_push (uuid_out); + free (uuid_out); + } + + /* build BIOS core.img. */ + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]) + { + char *load_cfg; + FILE *load_cfg_f; + char *output = grub_util_path_concat (3, boot_grub, "i386-pc", "eltorito.img"); + load_cfg = grub_util_make_temporary_file (); + + grub_util_info (N_("enabling %s support ..."), "BIOS"); + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + write_part (load_cfg_f, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]); + fclose (load_cfg_f); + + grub_install_push_module ("biosdisk"); + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "/boot/grub", output, + 0, load_cfg, + "i386-pc-eltorito", 0, + GRUB_COMPRESSION_AUTO); + + xorriso_push ("-b"); + xorriso_push ("boot/grub/i386-pc/eltorito.img"); + xorriso_push ("-no-emul-boot"); + xorriso_push ("-boot-load-size"); + xorriso_push ("4"); + xorriso_push ("-boot-info-table"); + if (system_area == SYS_AREA_COMMON) + { + if (check_xorriso ("grub2-boot-info")) + { + char *boot_hybrid = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "boot_hybrid.img"); + xorriso_push ("--grub2-boot-info"); + xorriso_push ("--grub2-mbr"); + xorriso_push (boot_hybrid); + } + else + { + FILE *sa, *bi; + size_t sz; + char buf[512]; + char *bin = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "boot.img"); + grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later.")); + sysarea_img = grub_util_make_temporary_file (); + sa = grub_util_fopen (sysarea_img, "wb"); + if (!sa) + grub_util_error (_("cannot open `%s': %s"), sysarea_img, + strerror (errno)); + bi = grub_util_fopen (sysarea_img, "wb"); + if (!bi) + grub_util_error (_("cannot open `%s': %s"), bin, + strerror (errno)); + fread (buf, 1, 512, bi); + fclose (bi); + fwrite (buf, 1, 512, sa); + + grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "/boot/grub", output, + 0, load_cfg, + "i386-pc", 0, + GRUB_COMPRESSION_AUTO); + sz = ftello (sa); + fflush (sa); + fsync (fileno (sa)); + fclose (sa); + + if (sz > 32768) + { + grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later.")); + } + else + { + xorriso_push ("-G"); + xorriso_push (sysarea_img); + } + } + } + grub_install_pop_module (); + grub_install_pop_module (); + } + + /** build multiboot core.img */ + grub_install_push_module ("pata"); + grub_install_push_module ("ahci"); + grub_install_push_module ("at_keyboard"); + make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf", GRUB_COMPRESSION_AUTO); + grub_install_pop_module (); + grub_install_pop_module (); + grub_install_pop_module (); + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386-ieee1275", "ofwx86.elf"); + + char *core_services = NULL; + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) + { + char *mach_ker, *sv, *label, *label_text; + FILE *f; + core_services = grub_util_path_concat (4, iso9660_dir, "System", "Library", "CoreServices"); + grub_install_mkdir_p (core_services); + + mach_ker = grub_util_path_concat (2, iso9660_dir, "mach_kernel"); + f = grub_util_fopen (mach_ker, "wb"); + fclose (f); + free (mach_ker); + + sv = grub_util_path_concat (2, core_services, "SystemVersion.plist"); + f = grub_util_fopen (sv, "wb"); + fprintf (f, "\n" + "\n" + " ProductBuildVersion\n" + " \n" + " ProductName\n" + " %s\n" + " ProductVersion\n" + " %s\n" + "\n" + "\n", product_name, product_version); + fclose (f); + free (sv); + label = grub_util_path_concat (2, core_services, ".disk_label"); + char *label_string = xasprintf ("%s %s", product_name, product_version); + grub_util_render_label (label_font, label_bgcolor ? : "white", + label_color ? : "black", label_string, label); + free (label); + label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails"); + f = grub_util_fopen (label_text, "wb"); + fprintf (f, "%s", label_string); + fclose (f); + free (label_string); + free (label_text); + if (system_area == SYS_AREA_COMMON) + { + xorriso_push ("-hfsplus"); + xorriso_push ("-apm-block-size"); + xorriso_push ("2048"); + xorriso_push ("-hfsplus-file-creator-type"); + xorriso_push ("chrp"); + xorriso_push ("tbxj"); + xorriso_push ("/System/Library/CoreServices/.disk_label"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + { + xorriso_push ("-hfs-bless-by"); + xorriso_push ("i"); + xorriso_push ("/System/Library/CoreServices/boot.efi"); + } + } + } + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI]) + { + char *efidir = grub_util_make_temporary_dir (); + char *efidir_efi = grub_util_path_concat (2, efidir, "efi"); + char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot"); + char *imgname, *img32, *img64, *img_mac = NULL; + char *efiimgfat; + grub_install_mkdir_p (efidir_efi_boot); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname); + free (imgname); + + img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64); + + img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); + free (imgname); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) + { + imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi"); + /* For old macs. Suggested by Peter Jones. */ + grub_install_copy_file (img32, imgname, 1); + } + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + img_mac = grub_util_path_concat (2, core_services, "boot.efi"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + && source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + grub_util_glue_efi (img32, img64, img_mac); + else if (source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + grub_install_copy_file (img64, img_mac, 1); + else if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) + grub_install_copy_file (img32, img_mac, 1); + + free (img_mac); + free (img32); + free (img64); + free (efidir_efi_boot); + + efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img"); + grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i", + efiimgfat, "::", NULL }); + grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL }); + xorriso_push ("--efi-boot"); + xorriso_push ("efi.img"); + xorriso_push ("-efi-boot-part"); + xorriso_push ("--efi-boot-image"); + + grub_util_unlink_recursive (efidir); + free (efiimgfat); + free (efidir_efi); + free (efidir); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) + { + char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], + "grub.chrp"); + char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], + "grub.chrp"); + char *bootx = grub_util_path_concat (2, core_services, "BootX"); + char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp"); + char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt"); + grub_install_copy_file (grub_chrp, bootx, 1); + grub_install_mkdir_p (ppc_chrp); + grub_install_copy_file (bisrc, bitgt, 1); + xorriso_link ("/System/Library/CoreServices/grub.elf", "/boot/grub/powerpc-ieee1275/core.elf"); + xorriso_link ("/boot/grub/powerpc.elf", "/boot/grub/powerpc-ieee1275/core.elf"); + /* FIXME: add PreP */ + if (system_area == SYS_AREA_COMMON) + { + xorriso_push ("-hfsplus-file-creator-type"); + xorriso_push ("chrp"); + xorriso_push ("tbxi"); + xorriso_push ("/System/Library/CoreServices/BootX"); + xorriso_push ("-hfs-bless-by"); + xorriso_push ("p"); + xorriso_push ("/System/Library/CoreServices"); + } + xorriso_push ("-sysid"); + xorriso_push ("PPC"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, + "sparc64-ieee1275-cdcore", "sparc64-ieee1275/core.img"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] + && system_area == SYS_AREA_SPARC) + { + char *cdboot; + FILE *in, *out; + char buf[512]; + sysarea_img = grub_util_make_temporary_file (); + cdboot = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275], + "cdboot.img"); + in = grub_util_fopen (cdboot, "rb"); + out = grub_util_fopen (sysarea_img, "wb"); + memset (buf, 0, 512); + fwrite (buf, 1, 512, out); + fread (buf, 1, 512, in); + fwrite (buf, 1, 512, out); + fclose (in); + fclose (out); + xorriso_push ("-G"); + xorriso_push (sysarea_img); + xorriso_push ("-B"); + xorriso_push (","); + xorriso_push ("--grub2-sparc-core"); + xorriso_push ("/boot/grub/sparc64-ieee1275/core.img"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips-arc", "mips-arc/core.img"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) + { + xorriso_link ("/boot/grub/mips-arc/grub", "/boot/grub/mips-arc/core.img"); + xorriso_link ("/boot/grub/mips-arc/sashARCS", "/boot/grub/mips-arc/core.img"); + xorriso_link ("/boot/grub/mips-arc/sash", "/boot/grub/mips-arc/core.img"); + } + if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC] && system_area == SYS_AREA_ARCS) + { + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/sashARCS"); + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/sash"); + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/grub"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe"); + + grub_install_push_module ("pata"); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf", GRUB_COMPRESSION_AUTO); + + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf", GRUB_COMPRESSION_XZ); + + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin", GRUB_COMPRESSION_XZ); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fulong2f-flash", "mipsel-fuloong2f.bin", GRUB_COMPRESSION_XZ); + + make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf", GRUB_COMPRESSION_AUTO); + + grub_install_push_module ("at_keyboard"); + + make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img", GRUB_COMPRESSION_AUTO); + + grub_install_push_module ("ahci"); + + make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf", GRUB_COMPRESSION_AUTO); + grub_install_pop_module (); + grub_install_pop_module (); + grub_install_pop_module (); + + if (rom_directory) + { + const struct + { + enum grub_install_plat plat; + const char *from, *to; + } roms[] = + { + {GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "roms/mipsel-qemu_mips.elf", "mipsel-qemu_mips.elf"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "loongson.elf", "mipsel-loongson.elf"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-yeeloong.bin", "mipsel-yeeloong.bin"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-fulong.bin", "mipsel-fulong.bin"}, + {GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "roms/mips-qemu_mips.elf", "mips-qemu_mips.elf"}, + {GRUB_INSTALL_PLATFORM_I386_QEMU, "roms/qemu.img", "qemu.img"}, + {GRUB_INSTALL_PLATFORM_I386_COREBOOT, "roms/coreboot.elf", "coreboot.elf"}, + }; + grub_size_t i; + for (i = 0; i < ARRAY_SIZE (roms); i++) + { + char *from = grub_util_path_concat (2, boot_grub, roms[i].from); + char *to = grub_util_path_concat (2, rom_directory, roms[i].to); + grub_install_copy_file (from, to, 0); + } + } + + xorriso_push ("--protective-msdos-label"); + xorriso_push ("-o"); + xorriso_push (output_image); + xorriso_push ("-r"); + xorriso_push (iso9660_dir); + xorriso_push ("--sort-weight"); + xorriso_push ("0"); + xorriso_push ("/"); + xorriso_push ("--sort-weight"); + xorriso_push ("1"); + xorriso_push ("/boot"); + int i; + for (i = 0; i < xorriso_tail_argc; i++) + xorriso_push (xorriso_tail_argv[i]); + + xorriso_argv[xorriso_argc] = NULL; + + grub_util_exec ((const char *const *)xorriso_argv); + + grub_util_unlink_recursive (iso9660_dir); + + if (sysarea_img) + grub_util_unlink (sysarea_img); + + free (core_services); + free (romdir); + return 0; +} diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in deleted file mode 100644 index 444ef85fd..000000000 --- a/util/grub-mkrescue.in +++ /dev/null @@ -1,493 +0,0 @@ -#!/bin/sh - -# Make GRUB rescue image -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 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. - -multiboot_dir="${libdir}/@PACKAGE@/i386-multiboot" -coreboot_dir="${libdir}/@PACKAGE@/i386-coreboot" -qemu_dir="${libdir}/@PACKAGE@/i386-qemu" -mipsel_qemu_dir="${libdir}/@PACKAGE@/mipsel-qemu_mips" -loongson_dir="${libdir}/@PACKAGE@/mipsel-loongson" -mips_qemu_dir="${libdir}/@PACKAGE@/mips-qemu_mips" -pc_dir="${libdir}/@PACKAGE@/i386-pc" -i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275" -efi32_dir="${libdir}/@PACKAGE@/i386-efi" -efi64_dir="${libdir}/@PACKAGE@/x86_64-efi" -ia64_dir="${libdir}/@PACKAGE@/ia64-efi" -sparc64_dir="${libdir}/@PACKAGE@/sparc64-ieee1275" -arcs_dir="${libdir}/@PACKAGE@/mips-arc" -arc_dir="${libdir}/@PACKAGE@/mipsel-arc" -ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275" -rom_directory= -grub_render_label="${bindir}/@grub_render_label@" -grub_glue_efi="${bindir}/@grub_glue_efi@" -label_font="${pkgdatadir}/unicode.pf2" -label_color="black" -label_bgcolor="white" -product_name="${PACKAGE_NAME}" -product_version="${PACKAGE_VERSION}" - -xorriso=xorriso - -# Usage: usage -# Print the usage. -usage () { - gettext_printf "Usage: %s [OPTION] SOURCE...\n" "$self" - # TRANSLATORS: it generates one single image which is bootable through any method. - gettext "Make GRUB CD-ROM, disk, pendrive and floppy bootable image."; echo - echo - filetrans="$(gettext FILE)" - print_option_help "-h, --help" "$(gettext "print this message and exit")" - print_option_help "-o, --output=$filetrans" "$(gettext "save output in FILE [required]")" - grub_print_install_files_help - print_option_help "--rom-directory=$(gettext "DIR")" "$(gettext "save ROM images in DIR [optional]")" - # TRANSLATORS: xorriso is a program for creating ISOs and burning CDs - print_option_help "--xorriso=$filetrans" "$(gettext "use FILE as xorriso [optional]")" - print_option_help "--grub-glue-efi=$filetrans" "$(gettext "use FILE as grub-glue-efi")" - print_option_help "--grub-render-label=$filetrans" "$(gettext "use FILE as grub-render-label")" - print_option_help "--label-font=$filetrans" "$(gettext "use FILE as font for label")" - print_option_help "--label-color=$(gettext "COLOR")" "$(gettext "use COLOR for label")" - print_option_help "--label-bgcolor=$(gettext "COLOR")" "$(gettext "use COLOR for label background")" - print_option_help "--product-name=$(gettext "STRING")" "$(gettext "use STRING as product name")" - print_option_help "--product-version=$(gettext "STRING")" "$(gettext "use STRING as product version")" - print_option_help "--sparc-boot" "$(gettext "enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc")" - print_option_help "--arcs-boot" "$(gettext "enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc")" - echo - gettext_printf "%s generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of \`%s'\n" "xorriso -as mkisofs -help" "$self" | grub_fmt - echo - gettext "Option -- switches to native xorriso command mode."; echo - echo - gettext "Report bugs to ."; echo - gettext "Mail xorriso support requests to ."; echo -} - -system_area=auto -mkimage_extra_arg= - -# Check the arguments. -while test $# -gt 0 -do - grub_process_install_options "$@" - case "$grub_process_install_options_consumed" in - 1) shift; continue;; - 2) shift; shift; continue;; - esac - - option=$1 - shift - - case "$option" in - -h | --help) - usage - exit 0 ;; - - -o | --output) - output_image=`argument $option "$@"`; shift ;; - --output=*) - output_image=`echo "$option" | sed 's/--output=//'` ;; - - --rom-directory) - rom_directory=`argument $option "$@"`; shift ;; - --rom-directory=*) - rom_directory=`echo "$option" | sed 's/--rom-directory=//'` ;; - - # Intentionally undocumented - --grub-mkimage-extra) - mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;; - --grub-mkimage-extra=*) - mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;; - - --sparc-boot) - system_area=sparc64 ;; - - --arcs-boot) - system_area=arcs ;; - - --product-name) - product_name=`argument $option "$@"`; shift ;; - --product-name=*) - product_name=`echo "$option" | sed 's/--product-name=//'` ;; - - --product-version) - product_version=`argument $option "$@"`; shift ;; - --product-version=*) - product_version=`echo "$option" | sed 's/--product-version=//'` ;; - - --grub-glue-efi) - grub_glue_efi=`argument $option "$@"`; shift ;; - --grub-glue-efi=*) - grub_glue_efi=`echo "$option" | sed 's/--grub-glue-efi=//'` ;; - - --grub-render-label) - grub_render_label=`argument $option "$@"`; shift ;; - --grub-render-label=*) - grub_render_label=`echo "$option" | sed 's/--grub-render-label=//'` ;; - - --label-font) - label_font=`argument $option "$@"`; shift ;; - --label-font=*) - label_font=`echo "$option" | sed 's/--label-font=//'` ;; - - --label-color) - label_color=`argument $option "$@"`; shift ;; - --label-color=*) - label_color=`echo "$option" | sed 's/--label-color=//'` ;; - - --label-bgcolor) - label_bgcolor=`argument $option "$@"`; shift ;; - --label-bgcolor=*) - label_bgcolor=`echo "$option" | sed 's/--label-bgcolor=//'` ;; - - --xorriso) - xorriso=`argument $option "$@"`; shift ;; - --xorriso=*) - xorriso=`echo "${option}" | sed 's/--xorriso=//'` ;; - - *) - source="${source} ${option} $@"; break ;; - esac -done - -if [ "x${output_image}" = x ] ; then - gettext "output file must be specified" >&2 - echo >&2 - usage - exit 1 -fi - -set $grub_mkimage dummy -if test -f "$1"; then - : -else - gettext_printf "%s: Not found.\n" "$1" 1>&2 - exit 1 -fi - -iso9660_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 -mkdir -p ${iso9660_dir}/boot/grub -mkdir -p ${iso9660_dir}/boot/grub/roms - -process_input_dir () -{ - grub_install_files "$1" "${iso9660_dir}/boot/grub" "$2" -} - -make_image () -{ - source_directory="$1" - platform=$2 - if ! test -e "${source_directory}"; then - return; - fi - - gettext_printf "Enabling %s support ...\n" "$2" - - load_cfg="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" - - (cat << EOF -search --fs-uuid --set=root ${iso_uuid} -set prefix=(\${root})/boot/grub -EOF - for i in $(cat "${source_directory}/partmap.lst") ${modules} ; do - echo "insmod $i" - done ; ) > "${load_cfg}" - - "$grub_mkimage" -O ${platform} -d "${source_directory}" -c "${load_cfg}" -o "$3" \ - $grub_decompression_module search iso9660 $4 - rm -rf "${load_cfg}" -} - -make_image_fwdisk () -{ - source_directory="$1" - platform=$2 - if ! test -e "${source_directory}"; then - return; - fi - - gettext_printf "Enabling %s support ...\n" "$2" - - "$grub_mkimage" -O ${platform} -d "${source_directory}" -p '()/boot/grub' -o "$3" \ - $grub_decompression_module iso9660 $4 -} - -if [ "${source_directory}" = "" ] ; then - if [ "$system_area" = auto ]; then - if test -e "${pc_dir}" || test -e "${ppc_dir}" \ - || test -e "${efi32_dir}" || test -e "${efi64_dir}"; then - system_area=common; - elif test -e "${sparc64_dir}" ; then - system_area=sparc64; - elif test -e "${arcs_dir}" ; then - system_area=arcs; - fi - fi - if test -e "${multiboot_dir}" ; then - process_input_dir "${multiboot_dir}" i386-multiboot - fi - if test -e "${coreboot_dir}" ; then - process_input_dir "${coreboot_dir}" i386-coreboot - fi - if test -e "${qemu_dir}" ; then - process_input_dir "${qemu_dir}" i386-qemu - fi - if test -e "${pc_dir}" ; then - process_input_dir "${pc_dir}" i386-pc - fi - if test -e "${i386_ieee1275_dir}" ; then - process_input_dir "${i386_ieee1275_dir}" i386-ieee1275 - fi - if test -e "${efi32_dir}" ; then - process_input_dir "${efi32_dir}" i386-efi - fi - if test -e "${efi64_dir}" ; then - process_input_dir "${efi64_dir}" x86_64-efi - fi - if test -e "${ia64_dir}" ; then - process_input_dir "${ia64_dir}" ia64-efi - fi - if test -e "${mips_qemu_dir}" ; then - process_input_dir "${mips_qemu_dir}" mips-qemu_mips - fi - if test -e "${mipsel_qemu_dir}" ; then - process_input_dir "${mipsel_qemu_dir}" mipsel-qemu_mips - fi - if test -e "${loongson_dir}" ; then - process_input_dir "${loongson_dir}" mipsel-loongson - fi - if test -e "${ppc_dir}" ; then - process_input_dir "${ppc_dir}" powerpc-ieee1275 - fi - if test -e "${sparc64_dir}" ; then - process_input_dir "${sparc64_dir}" sparc64-ieee1275 - fi - if test -e "${arcs_dir}" ; then - process_input_dir "${arcs_dir}" mips-arc - fi - if test -e "${arc_dir}" ; then - process_input_dir "${arc_dir}" mipsel-arc - fi -else - . "${source_directory}"/modinfo.sh - process_input_dir "${source_directory}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} - multiboot_dir= - pc_dir= - efi32_dir= - efi64_dir= - ia64_dir= - coreboot_dir= - qemu_dir= - mipsel_qemu_dir= - mips_qemu_dir= - loongson_dir= - ppc_dir= - i386_ieee1275_dir= - sparc64_dir= - arcs_dir= - arc_dir= - case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in - i386-multiboot) multiboot_dir="${source_directory}" ;; - i386-coreboot) coreboot_dir="${source_directory}" ;; - i386-qemu) qemu_dir="${source_directory}" ;; - i386-pc) pc_dir="${source_directory}"; system_area=common;; - i386-efi) efi32_dir="${source_directory}"; system_area=common ;; - x86_64-efi) efi64_dir="${source_directory}"; system_area=common ;; - ia64-efi) ia64_dir="${source_directory}" ;; - mipsel-qemu_mips) mipsel_qemu_dir="${source_directory}" ;; - mipsel-loongson) loongson_dir="${source_directory}" ;; - mips-qemu_mips) mips_qemu_dir="${source_directory}" ;; - powerpc-ieee1275) ppc_dir="${source_directory}"; system_area=common ;; - sparc64-ieee1275) sparc64_dir="${source_directory}"; system_area=sparc64 ;; - mips-arc) arcs_dir="${source_directory}"; system_area=arcs ;; - mipsel-arc) arc_dir="${source_directory}" ;; - i386-ieee1275) i386_ieee1275_dir="${source_directory}" ;; - esac -fi - -# obtain date-based UUID -iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) -grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" - -# build BIOS core.img -if test -e "${pc_dir}" ; then - gettext_printf "Enabling %s support ...\n" "BIOS" - load_cfg="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" - core_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 - - (for i in $(cat "${pc_dir}/partmap.lst") ${modules} ; do - echo "insmod $i" - done ;) > "${load_cfg}" - - "$grub_mkimage" -O i386-pc -d "${pc_dir}/" -o "${core_img}" -c "$load_cfg" --prefix=/boot/grub \ - $grub_decompression_module iso9660 biosdisk - cat "${pc_dir}/cdboot.img" "${core_img}" > "${iso9660_dir}/boot/grub/i386-pc/eltorito.img" - - grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-load-size 4 -boot-info-table" - if [ "$system_area" = common ]; then - if "${xorriso}" -as mkisofs -help 2>&1 | fgrep "grub2-boot-info" >/dev/null; then - grub_mkisofs_arguments="${grub_mkisofs_arguments} --grub2-boot-info --grub2-mbr ${pc_dir}/boot_hybrid.img" - else - gettext "Your xorriso doesn't support \`--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later." - echo - sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 - cat "${pc_dir}/boot.img" "${core_img}" > "${sysarea_img}" - if [ "$(wc -c "${sysarea_img}" | awk '{ print $1; }')" -gt 32768 ]; then - gettext "Your xorriso doesn't support \`--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later." - echo - else - grub_mkisofs_arguments="${grub_mkisofs_arguments} -G ${sysarea_img}" - fi - fi - fi - - rm -f "${core_img}" -fi - -# build multiboot core.img -make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/grub/i386-multiboot/core.elf" "pata ahci at_keyboard" - -make_image_fwdisk "${i386_ieee1275_dir}" i386-ieee1275 "${iso9660_dir}/boot/grub/ofwx86.elf" "" - -if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; then - efi_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 - mkdir -p "${efi_dir}/efi/boot" - - # build bootia64.efi - make_image_fwdisk "${ia64_dir}" ia64-efi "${efi_dir}"/efi/boot/bootia64.efi "" - # build bootx64.efi - make_image_fwdisk "${efi64_dir}" x86_64-efi "${efi_dir}"/efi/boot/bootx64.efi "" - # build bootia32.efi - make_image_fwdisk "${efi32_dir}" i386-efi "${efi_dir}"/efi/boot/bootia32.efi "" - if [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then - # For old macs. Suggested by Peter Jones. - cp "${efi_dir}"/efi/boot/bootia32.efi "${efi_dir}"/efi/boot/boot.efi - fi - - if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] || [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then - mkdir -p "${iso9660_dir}"/System/Library/CoreServices - fi - - if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] && [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then - "$grub_glue_efi" -6 "${efi_dir}"/efi/boot/bootx64.efi -3 "${efi_dir}"/efi/boot/bootia32.efi -o "${iso9660_dir}"/System/Library/CoreServices/boot.efi - elif [ -e "${efi_dir}"/efi/boot/bootx64.efi ]; then - cp "${efi_dir}"/efi/boot/bootx64.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi - elif [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then - cp "${efi_dir}"/efi/boot/bootia32.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi - fi - - mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: - mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ - rm -rf ${efi_dir} - grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img -efi-boot-part --efi-boot-image" -fi - -make_image_fwdisk "${ppc_dir}" powerpc-ieee1275 "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" "" -if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] || [ -e "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ]; then - mkdir -p "${iso9660_dir}"/System/Library/CoreServices - touch "${iso9660_dir}/mach_kernel" - cat > "${iso9660_dir}/System/Library/CoreServices/SystemVersion.plist" < - - ProductBuildVersion - - ProductName - ${product_name} - ProductVersion - ${product_version} - - -EOF - "$grub_render_label" -f "$label_font" -b "$label_bgcolor" -c "$label_color" -t "${product_name} ${product_version}" -o "${iso9660_dir}/System/Library/CoreServices/.disk_label" - echo "${product_name} ${product_version}" > "${iso9660_dir}/System/Library/CoreServices/.disk_label.contentDetails" - if [ "$system_area" = common ]; then - grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -apm-block-size 2048 -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label" - fi -fi - -if [ -e "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ] ; then - cp "${ppc_dir}/grub.chrp" "${iso9660_dir}"/System/Library/CoreServices/BootX - mkdir -p "${iso9660_dir}"/ppc/chrp - cp "${ppc_dir}/bootinfo.txt" "${iso9660_dir}"/ppc/bootinfo.txt - grub_mkisofs_arguments="${grub_mkisofs_arguments} /System/Library/CoreServices/grub.elf=${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf /boot/grub/powerpc.elf=${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" - # FIXME: add PreP - if [ "$system_area" = common ]; then - grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus-file-creator-type chrp tbxi /System/Library/CoreServices/BootX -hfs-bless-by p /System/Library/CoreServices" - fi - grub_mkisofs_arguments="${grub_mkisofs_arguments} -sysid PPC" -fi - -if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] && [ "$system_area" = common ]; then - grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfs-bless-by i /System/Library/CoreServices/boot.efi" -fi - -make_image_fwdisk "${sparc64_dir}" sparc64-ieee1275-cdcore "${iso9660_dir}/boot/grub/sparc64-ieee1275/core.img" "" -if [ -e "${iso9660_dir}"/boot/grub/sparc64-ieee1275/core.img ] && [ "$system_area" = sparc64 ]; then - sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 - dd if=/dev/zero count=1 bs=512 | cat - "${sparc64_dir}"/cdboot.img > "$sysarea_img" - grub_mkisofs_arguments="${grub_mkisofs_arguments} -G $sysarea_img -B , --grub2-sparc-core /boot/grub/sparc64-ieee1275/core.img" -fi - -make_image_fwdisk "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" "" -if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ]; then - grub_mkisofs_arguments="${grub_mkisofs_arguments} /boot/grub/mips-arc/grub=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sashARCS=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sash=${iso9660_dir}/boot/grub/mips-arc/core.img" -fi -if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ] && [ "$system_area" = arcs ]; then - grub_mkisofs_arguments="${grub_mkisofs_arguments} -mips-boot /boot/grub/mips-arc/sashARCS -mips-boot /boot/grub/mips-arc/sash -mips-boot /boot/grub/mips-arc/grub" -fi - -make_image_fwdisk "${arc_dir}" mipsel-arc "${iso9660_dir}/boot/grub/arc.exe" "" - -make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "pata" -if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then - cp "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "${rom_directory}/mipsel-qemu_mips.elf" -fi - -make_image "${loongson_dir}" mipsel-loongson-elf "${iso9660_dir}/boot/grub/loongson.elf" "pata -C xz" -if [ -e "${iso9660_dir}/boot/grub/loongson.elf" ] && [ -d "${rom_directory}" ]; then - cp "${iso9660_dir}/boot/grub/loongson.elf" "${rom_directory}/mipsel-loongson.elf" -fi -make_image "${loongson_dir}" mipsel-yeeloong-flash "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" "pata -C xz" -if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" ] && [ -d "${rom_directory}" ]; then - cp "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" "${rom_directory}/mipsel-yeeloong.bin" -fi - -make_image "${loongson_dir}" mipsel-fuloong2f-flash "${iso9660_dir}/boot/grub/roms/mipsel-fuloong2f.bin" "pata -C xz" -if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-fulong.bin" ] && [ -d "${rom_directory}" ]; then - cp "${iso9660_dir}/boot/grub/roms/mipsel-fulong.bin" "${rom_directory}/mipsel-fulong.bin" -fi - -make_image "${mips_qemu_dir}" mips-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" "pata" -if [ -e "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then - cp "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" "${rom_directory}/mips-qemu_mips.elf" -fi -make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/grub/roms/qemu.img" "pata at_keyboard" -if [ -e "${iso9660_dir}/boot/grub/roms/qemu.img" ] && [ -d "${rom_directory}" ]; then - cp "${iso9660_dir}/boot/grub/roms/qemu.img" "${rom_directory}/qemu.img" -fi -make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/grub/roms/coreboot.elf" "pata ahci at_keyboard" -if [ -e "${iso9660_dir}/boot/grub/roms/coreboot.elf" ] && [ -d "${rom_directory}" ]; then - cp "${iso9660_dir}/boot/grub/roms/coreboot.elf" "${rom_directory}/coreboot.elf" -fi - -# build iso image -"${xorriso}" -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o "${output_image}" -r "${iso9660_dir}" --sort-weight 0 / --sort-weight 1 /boot ${source} -rm -rf "${iso9660_dir}" - -rm -f "${sysarea_img}" - -exit 0 diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c new file mode 100644 index 000000000..774af2f79 --- /dev/null +++ b/util/grub-mkstandalone.c @@ -0,0 +1,372 @@ + +/* + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 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 + +static grub_compression_t compression; +static char *output_image; +static char **files; +static int nfiles; +const struct grub_install_image_target_desc *format; +static FILE *memdisk; + +enum + { + OPTION_OUTPUT = 'o', + OPTION_FORMAT = 'C', + OPTION_COMPRESION = 'C' + }; + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"output", 'o', N_("FILE"), + 0, N_("save output in FILE [required]"), 2}, + {"format", 'O', N_("FILE"), 0, 0, 2}, + {"compression", 'C', N_("xz|none|auto"), + 0, N_("choose the compression to use for core image"), 2}, + {0, 0, 0, 0, 0, 0} +}; + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case 'O': + { + char *formats = grub_install_get_image_targets_string (), *ret; + ret = xasprintf ("%s\n%s %s", _("generate an image in FORMAT"), + _("available formats:"), formats); + free (formats); + return ret; + } + default: + return grub_install_help_filter (key, text, input); + } +} + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + + switch (key) + { + + case 'o': + if (output_image) + free (output_image); + + output_image = xstrdup (arg); + break; + + case 'O': + { + format = grub_install_get_image_target (arg); + if (!format) + { + printf (_("unknown target format %s\n"), arg); + argp_usage (state); + exit (1); + } + break; + } + + case 'C': + if (grub_strcmp (arg, "xz") == 0) + { +#ifdef HAVE_LIBLZMA + compression = GRUB_COMPRESSION_XZ; +#else + grub_util_error ("%s", + _("grub-mkimage is compiled without XZ support")); +#endif + } + else if (grub_strcmp (arg, "none") == 0) + compression = GRUB_COMPRESSION_NONE; + else if (grub_strcmp (arg, "auto") == 0) + compression = GRUB_COMPRESSION_AUTO; + else + grub_util_error (_("Unknown compression format %s"), arg); + break; + case ARGP_KEY_ARG: + files[nfiles++] = xstrdup (arg); + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +struct argp argp = { + options, argp_parser, N_("[OPTION] SOURCE..."), + N_("Generate a standalone image (containing all modules) in the selected format")"\v"N_("Graft point syntax (E.g. /boot/grub/grub.cfg=./grub.cfg) is accepted"), + NULL, help_filter, NULL +}; + +/* tar support */ +#define MAGIC "ustar" +struct head +{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; + char pad[12]; +} __attribute__ ((packed)); + +static void +write_zeros (unsigned rsz) +{ + char buf[512]; + + memset (buf, 0, 512); + fwrite (buf, 1, rsz, memdisk); +} + +static void +write_pad (unsigned sz) +{ + write_zeros ((~sz + 1) & 511); +} + +static void +set_tar_value (char *field, grub_uint32_t val, + unsigned len) +{ + unsigned i; + for (i = 0; i < len - 1; i++) + field[len - 2 - i] = '0' + ((val >> (3 * i)) & 7); +} + +static void +compute_checksum (struct head *hd) +{ + unsigned int chk = 0; + unsigned char *ptr; + memset (hd->chksum, ' ', 8); + for (ptr = (unsigned char *) hd; ptr < (unsigned char *) (hd + 1); ptr++) + chk += *ptr; + set_tar_value (hd->chksum, chk, 8); +} + +static void +add_tar_file (const char *from, + const char *to) +{ + char *tcn; + const char *iptr; + char *optr; + struct head hd; + grub_util_fd_t in; + ssize_t r; + grub_uint32_t mtime = 0; + grub_uint32_t size; + + COMPILE_TIME_ASSERT (sizeof (hd) == 512); + + if (grub_util_is_special_file (from)) + return; + + mtime = grub_util_get_mtime (from); + + optr = tcn = xmalloc (strlen (to) + 1); + for (iptr = to; *iptr == '/'; iptr++); + for (; *iptr; iptr++) + if (!(iptr[0] == '/' && iptr[1] == '/')) + *optr++ = *iptr; + *optr = '\0'; + + if (grub_util_is_directory (from)) + { + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (from); + + while ((de = grub_util_fd_readdir (d))) + { + char *fp, *tfp; + if (strcmp (de->d_name, ".") == 0) + continue; + if (strcmp (de->d_name, "..") == 0) + continue; + fp = grub_util_path_concat (2, from, de->d_name); + tfp = xasprintf ("%s/%s", to, de->d_name); + add_tar_file (fp, tfp); + free (fp); + } + grub_util_fd_closedir (d); + free (tcn); + return; + } + + if (optr - tcn > 99) + { + memset (&hd, 0, sizeof (hd)); + memcpy (hd.name, tcn, 99); + memcpy (hd.mode, "0000600", 7); + memcpy (hd.uid, "0001750", 7); + memcpy (hd.gid, "0001750", 7); + + set_tar_value (hd.size, optr - tcn, 12); + set_tar_value (hd.mtime, mtime, 12); + hd.typeflag = 'L'; + memcpy (hd.magic, "ustar ", 7); + memcpy (hd.uname, "grub", 4); + memcpy (hd.gname, "grub", 4); + + compute_checksum (&hd); + + fwrite (&hd, 1, sizeof (hd), memdisk); + fwrite (tcn, 1, optr - tcn, memdisk); + + write_pad (optr - tcn); + } + + in = grub_util_fd_open (from, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (in)) + grub_util_error (_("cannot open `%s': %s"), from, grub_util_fd_strerror ()); + + if (!grub_install_copy_buffer) + grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE); + + size = grub_util_get_fd_size (in, from, NULL); + + memset (&hd, 0, sizeof (hd)); + memcpy (hd.name, tcn, optr - tcn < 99 ? optr - tcn : 99); + memcpy (hd.mode, "0000600", 7); + memcpy (hd.uid, "0001750", 7); + memcpy (hd.gid, "0001750", 7); + + set_tar_value (hd.size, size, 12); + set_tar_value (hd.mtime, mtime, 12); + hd.typeflag = '0'; + memcpy (hd.magic, "ustar ", 7); + memcpy (hd.uname, "grub", 4); + memcpy (hd.gname, "grub", 4); + + compute_checksum (&hd); + + fwrite (&hd, 1, sizeof (hd), memdisk); + + while (1) + { + r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE); + if (r <= 0) + break; + fwrite (grub_install_copy_buffer, 1, r, memdisk); + } + grub_util_fd_close (in); + + write_pad (size); +} + +int +main (int argc, char *argv[]) +{ + const char *pkglibdir; + int i; + + grub_util_host_init (&argc, &argv); + + files = xmalloc ((argc + 1) * sizeof (files[0])); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + pkglibdir = grub_util_get_pkglibdir (); + + if (!output_image) + grub_util_error ("%s", _("output file must be specified")); + + if (!format) + grub_util_error ("%s", _("Target format not specified (use the -O option).")); + + if (!grub_install_source_directory) + grub_install_source_directory = grub_util_path_concat (2, pkglibdir, grub_util_get_target_dirname (format)); + + enum grub_install_plat plat = grub_install_get_target (grub_install_source_directory); + + char *memdisk_dir = grub_util_make_temporary_dir (); + char *boot_grub = grub_util_path_concat (3, memdisk_dir, "boot", "grub"); + grub_install_copy_files (grub_install_source_directory, + boot_grub, plat); + + char *memdisk_img = grub_util_make_temporary_file (); + + memdisk = grub_util_fopen (memdisk_img, "wb"); + + add_tar_file (memdisk_dir, ""); + for (i = 0; i < nfiles; i++) + { + char *eq = grub_strchr (files[i], '='); + char *from, *to; + if (!eq) + { + from = files[i]; + to = files[i]; + } + else + { + *eq = '\0'; + to = files[i]; + from = eq + 1; + } + while (*to == '/') + to++; + add_tar_file (from, to); + } + write_zeros (512); + + fclose (memdisk); + + grub_util_unlink_recursive (memdisk_dir); + + grub_install_push_module ("memdisk"); + grub_install_push_module ("tar"); + + grub_install_make_image_wrap (grub_install_source_directory, + "(memdisk)/boot/grub", output_image, + memdisk_img, NULL, + grub_util_get_target_name (format), 0, + compression); + + grub_util_unlink (memdisk_img); + return 0; +} diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in deleted file mode 100644 index b692c481c..000000000 --- a/util/grub-mkstandalone.in +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/sh - -# Make GRUB rescue image -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 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. - -compression=auto -format= -source= - -# Usage: usage -# Print the usage. -usage () { - formats="i386-coreboot i386-multiboot i386-pc i386-pc-pxe i386-efi i386-ieee1275 i386-qemu x86_64-efi mipsel-yeeloong-flash mipsel-fuloong2f-flash mipsel-loongson-elf powerpc-ieee1275 sparc64-ieee1275-raw sparc64-ieee1275-aout ia64-efi mips-arc mipsel-qemu_mips-elf mips-qemu_mips-flash mipsel-qemu_mips-flash mips-qemu_mips-elf" - gettext_printf "Usage: %s [OPTION] SOURCE...\n" "$self" - gettext "Generate a standalone image (containing all modules) in the selected format" - echo - print_option_help "-h, --help" "$(gettext "print this message and exit")" - print_option_help "-o, --output=$(gettext FILE)" "$(gettext "save output in FILE [required]")" - print_option_help "-O, --format=$(gettext "FORMAT")" "$(gettext "generate an image in FORMAT")"; echo - print_option_help "" "$(gettext "available formats:") $formats" - echo - print_option_help "-C, --compression=(xz|none|auto)" "$(gettext "choose the compression to use for core image")" - grub_print_install_files_help - echo - gettext "Report bugs to ."; echo -} - -# Check the arguments. -while test $# -gt 0 -do - grub_process_install_options "$@" - case "$grub_process_install_options_consumed" in - 1) shift; continue;; - 2) shift; shift; continue;; - esac - - option=$1 - shift - - case "$option" in - -h | --help) - usage - exit 0 ;; - - -o | --output) - output_image=`argument $option "$@"`; shift ;; - --output=*) - output_image=`echo "$option" | sed 's/--output=//'` ;; - - --compression | -C) - compression=`argument $option "$@"`; shift ;; - --compression=*) - compression=`echo "${option}" | sed 's/--compression=//'` ;; - - --format | -O) - format=`argument $option "$@"`; shift ;; - --format=*) - format=`echo "${option}" | sed 's/--format=//'` ;; - - *) - source="${source} ${option} $@"; break ;; - esac -done - -if [ "x${output_image}" = x ] ; then - gettext "output file must be specified" >&2 - echo >&2 - usage - exit 1 -fi - -if [ "x${format}" = x ] ; then - gettext "Target format not specified (use the -O option)." >&2 - echo >&2 - exit 1 -fi - -if [ "x$source_directory" = x ] ; then - cpu="`echo $format | awk -F - '{ print $1; }'`" - platform="`echo $format | awk -F - '{ print $2; }'`" - case "$platform" in - yeeloong | fuloong | fuloong2f | fuloong2e) - platform=loongson ;; - esac - case "$cpu-$platform" in - mips-loongson) - cpu=mipsel ;; - esac - source_directory="${libdir}/@PACKAGE@/$cpu-$platform" -fi - -. "${source_directory}"/modinfo.sh - -set $grub_mkimage dummy -if test -f "$1"; then - : -else - echo "$1: Not found." 1>&2 - exit 1 -fi - -memdisk_dir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -grub_install_files "${source_directory}" "${memdisk_dir}"/boot/grub "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" -for file in $source; do - cp -f "$file" "${memdisk_dir}"/"$file"; -done - -memdisk_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 - -(cd "${memdisk_dir}"; tar -cf - * $source) > "${memdisk_img}" -rm -rf "${memdisk_dir}" -"$grub_mkimage" -O "${format}" -C "$compression" -d "${source_directory}" -m "${memdisk_img}" -o "$output_image" --prefix='(memdisk)/boot/grub' memdisk tar $grub_decompression_module $modules -rm -rf "${memdisk_img}" - -exit 0 diff --git a/util/grub-probe.c b/util/grub-probe.c index d29d562aa..db68d61f6 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -155,135 +155,6 @@ probe_raid_level (grub_disk_t disk) return ((struct grub_diskfilter_lv *) disk->data)->segments->type; } -/* Since OF path names can have "," characters in them, and GRUB - internally uses "," to indicate partitions (unlike OF which uses - ":" for this purpose) we escape such commas. */ -static char * -escape_of_path (const char *orig_path) -{ - char *new_path, *d, c; - const char *p; - - if (!strchr (orig_path, ',')) - return (char *) xstrdup (orig_path); - - new_path = xmalloc (strlen (orig_path) * 2 + 1); - - p = orig_path; - d = new_path; - while ((c = *p++) != '\0') - { - if (c == ',') - *d++ = '\\'; - *d++ = c; - } - *d = 0; - - return new_path; -} - -static char * -guess_bios_drive (const char *orig_path) -{ - char *canon; - char *ptr; - canon = canonicalize_file_name (orig_path); - if (!canon) - return NULL; - ptr = strrchr (orig_path, '/'); - if (ptr) - ptr++; - else - ptr = canon; - if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd') - { - int num = ptr[2] - 'a'; - free (canon); - return xasprintf ("hd%d", num); - } - if (ptr[0] == 'f' && ptr[1] == 'd') - { - int num = atoi (ptr + 2); - free (canon); - return xasprintf ("fd%d", num); - } - free (canon); - return NULL; -} - -static char * -guess_efi_drive (const char *orig_path) -{ - char *canon; - char *ptr; - canon = canonicalize_file_name (orig_path); - if (!canon) - return NULL; - ptr = strrchr (orig_path, '/'); - if (ptr) - ptr++; - else - ptr = canon; - if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd') - { - int num = ptr[2] - 'a'; - free (canon); - return xasprintf ("hd%d", num); - } - if (ptr[0] == 'f' && ptr[1] == 'd') - { - int num = atoi (ptr + 2); - free (canon); - return xasprintf ("fd%d", num); - } - free (canon); - return NULL; -} - -static char * -guess_baremetal_drive (const char *orig_path) -{ - char *canon; - char *ptr; - canon = canonicalize_file_name (orig_path); - if (!canon) - return NULL; - ptr = strrchr (orig_path, '/'); - if (ptr) - ptr++; - else - ptr = canon; - if (ptr[0] == 'h' && ptr[1] == 'd') - { - int num = ptr[2] - 'a'; - free (canon); - return xasprintf ("ata%d", num); - } - if (ptr[0] == 's' && ptr[1] == 'd') - { - int num = ptr[2] - 'a'; - free (canon); - return xasprintf ("ahci%d", num); - } - free (canon); - return NULL; -} - -static void -print_full_name (const char *drive, grub_device_t dev) -{ - char *dname = escape_of_path (drive); - if (dev->disk->partition) - { - char *pname = grub_partition_get_name (dev->disk->partition); - printf ("%s,%s", dname, pname); - free (pname); - } - else - printf ("%s", dname); - free (dname); -} - static void probe_abstraction (grub_disk_t disk) { @@ -513,34 +384,34 @@ probe (const char *path, char **device_names, char delim) p = grub_stpcpy (tmp, "ieee1275/"); strcpy (p, ofpath); printf ("--hint-ieee1275='"); - print_full_name (tmp, dev); + grub_util_fprint_full_disk_name (stdout, tmp, dev); printf ("' "); free (tmp); } - biosname = guess_bios_drive (*curdev); + biosname = grub_util_guess_bios_drive (*curdev); if (biosname) { printf ("--hint-bios="); - print_full_name (biosname, dev); + grub_util_fprint_full_disk_name (stdout, biosname, dev); printf (" "); } free (biosname); - efi = guess_efi_drive (*curdev); + efi = grub_util_guess_efi_drive (*curdev); if (efi) { printf ("--hint-efi="); - print_full_name (efi, dev); + grub_util_fprint_full_disk_name (stdout, efi, dev); printf (" "); } free (efi); - bare = guess_baremetal_drive (*curdev); + bare = grub_util_guess_baremetal_drive (*curdev); if (bare) { printf ("--hint-baremetal="); - print_full_name (bare, dev); + grub_util_fprint_full_disk_name (stdout, bare, dev); printf (" "); } free (bare); @@ -551,7 +422,7 @@ probe (const char *path, char **device_names, char delim) if (map) { printf ("--hint='"); - print_full_name (map, dev); + grub_util_fprint_full_disk_name (stdout, map, dev); printf ("' "); } if (curdrive[1]) @@ -568,7 +439,7 @@ probe (const char *path, char **device_names, char delim) || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT) && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID) { - print_full_name (dev->disk->name, dev); + grub_util_fprint_full_disk_name (stdout, dev->disk->name, dev); putchar (delim); continue; } @@ -580,16 +451,16 @@ probe (const char *path, char **device_names, char delim) map = grub_util_biosdisk_get_compatibility_hint (dev->disk); if (map) { - print_full_name (map, dev); + grub_util_fprint_full_disk_name (stdout, map, dev); putchar (delim); grub_device_close (dev); /* Compatibility hint is one device only. */ break; } - biosname = guess_bios_drive (*curdev); + biosname = grub_util_guess_bios_drive (*curdev); if (biosname) { - print_full_name (biosname, dev); + grub_util_fprint_full_disk_name (stdout, biosname, dev); putchar (delim); } free (biosname); @@ -603,10 +474,10 @@ probe (const char *path, char **device_names, char delim) if (print == PRINT_BIOS_HINT) { char *biosname; - biosname = guess_bios_drive (*curdev); + biosname = grub_util_guess_bios_drive (*curdev); if (biosname) { - print_full_name (biosname, dev); + grub_util_fprint_full_disk_name (stdout, biosname, dev); putchar (delim); } free (biosname); @@ -622,7 +493,7 @@ probe (const char *path, char **device_names, char delim) map = grub_util_biosdisk_get_compatibility_hint (dev->disk); if (map) { - print_full_name (map, dev); + grub_util_fprint_full_disk_name (stdout, map, dev); putchar (delim); } @@ -632,7 +503,7 @@ probe (const char *path, char **device_names, char delim) char *p; p = grub_stpcpy (tmp, "ieee1275/"); strcpy (p, ofpath); - print_full_name (tmp, dev); + grub_util_fprint_full_disk_name (stdout, tmp, dev); free (tmp); putchar (delim); } @@ -644,17 +515,17 @@ probe (const char *path, char **device_names, char delim) { char *biosname; const char *map; - biosname = guess_efi_drive (*curdev); + biosname = grub_util_guess_efi_drive (*curdev); map = grub_util_biosdisk_get_compatibility_hint (dev->disk); if (map) { - print_full_name (map, dev); + grub_util_fprint_full_disk_name (stdout, map, dev); putchar (delim); } if (biosname) { - print_full_name (biosname, dev); + grub_util_fprint_full_disk_name (stdout, biosname, dev); putchar (delim); } @@ -668,17 +539,17 @@ probe (const char *path, char **device_names, char delim) char *biosname; const char *map; - biosname = guess_baremetal_drive (*curdev); + biosname = grub_util_guess_baremetal_drive (*curdev); map = grub_util_biosdisk_get_compatibility_hint (dev->disk); if (map) { - print_full_name (map, dev); + grub_util_fprint_full_disk_name (stdout, map, dev); putchar (delim); } if (biosname) { - print_full_name (biosname, dev); + grub_util_fprint_full_disk_name (stdout, biosname, dev); putchar (delim); } @@ -694,7 +565,7 @@ probe (const char *path, char **device_names, char delim) map = grub_util_biosdisk_get_compatibility_hint (dev->disk); if (map) { - print_full_name (map, dev); + grub_util_fprint_full_disk_name (stdout, map, dev); putchar (delim); } diff --git a/util/misc.c b/util/misc.c index 8b6a678fa..0de340bbe 100644 --- a/util/misc.c +++ b/util/misc.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #define ENABLE_RELOCATABLE 0 #ifdef GRUB_BUILD @@ -256,15 +256,3 @@ void grub_register_exported_symbols (void) { } - -#ifdef GRUB_UTIL -void -grub_util_init_nls (void) -{ -#if (defined(ENABLE_NLS) && ENABLE_NLS) - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ -} -#endif diff --git a/util/mkimage.c b/util/mkimage.c index a5a683b98..4a510228c 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -66,7 +66,7 @@ struct grub_install_image_target_desc IMAGE_I386_IEEE1275, IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, - IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN + IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO } id; enum { @@ -174,6 +174,22 @@ static const struct grub_install_image_target_desc image_targets[] = .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, .default_compression = GRUB_COMPRESSION_LZMA }, + { + .dirname = "i386-pc", + .names = { "i386-pc-eltorito", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC_ELTORITO, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression = GRUB_COMPRESSION_LZMA + }, { .dirname = "i386-efi", .names = { "i386-efi", NULL }, @@ -826,6 +842,12 @@ grub_util_get_target_dirname (const struct grub_install_image_target_desc *t) return t->dirname; } +const char * +grub_util_get_target_name (const struct grub_install_image_target_desc *t) +{ + return t->names[0]; +} + char * grub_install_get_image_targets_string (void) { @@ -874,7 +896,8 @@ grub_install_generate_image (const char *dir, const char *prefix, comp = image_target->default_compression; if (image_target->id == IMAGE_I386_PC - || image_target->id == IMAGE_I386_PC_PXE) + || image_target->id == IMAGE_I386_PC_PXE + || image_target->id == IMAGE_I386_PC_ELTORITO) comp = GRUB_COMPRESSION_LZMA; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); @@ -1105,7 +1128,8 @@ grub_install_generate_image (const char *dir, const char *prefix, decompress_img = grub_util_read_image (decompress_path); if ((image_target->id == IMAGE_I386_PC - || image_target->id == IMAGE_I386_PC_PXE) + || image_target->id == IMAGE_I386_PC_PXE + || image_target->id == IMAGE_I386_PC_ELTORITO) && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) grub_util_error ("%s", _("Decompressor is too big")); @@ -1149,6 +1173,7 @@ grub_install_generate_image (const char *dir, const char *prefix, { case IMAGE_I386_PC: case IMAGE_I386_PC_PXE: + case IMAGE_I386_PC_ELTORITO: if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000 || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS)) || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)) @@ -1185,6 +1210,7 @@ grub_install_generate_image (const char *dir, const char *prefix, { case IMAGE_I386_PC: case IMAGE_I386_PC_PXE: + case IMAGE_I386_PC_ELTORITO: { unsigned num; char *boot_path, *boot_img; @@ -1219,6 +1245,21 @@ grub_install_generate_image (const char *dir, const char *prefix, } } + if (image_target->id == IMAGE_I386_PC_ELTORITO) + { + char *eltorito_path, *eltorito_img; + size_t eltorito_size; + + eltorito_path = grub_util_get_path (dir, "cdboot.img"); + eltorito_size = grub_util_get_image_size (eltorito_path); + eltorito_img = grub_util_read_image (eltorito_path); + + grub_util_write_image (eltorito_img, eltorito_size, out, + outname); + free (eltorito_img); + free (eltorito_path); + } + 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) @@ -1764,6 +1805,7 @@ grub_install_generate_image (const char *dir, const char *prefix, grub_util_write_image (core_img, core_size, out, outname); free (core_img); free (kernel_path); + free (rel_section); while (path_list) { diff --git a/util/probe.c b/util/probe.c new file mode 100644 index 000000000..c389f5dcf --- /dev/null +++ b/util/probe.c @@ -0,0 +1,172 @@ +/* grub-probe.c - probe device information for a given path */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009,2010,2013 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 + +/* Since OF path names can have "," characters in them, and GRUB + internally uses "," to indicate partitions (unlike OF which uses + ":" for this purpose) we escape such commas. */ +static char * +escape_of_path (const char *orig_path) +{ + char *new_path, *d, c; + const char *p; + + if (!strchr (orig_path, ',')) + return (char *) xstrdup (orig_path); + + new_path = xmalloc (strlen (orig_path) * 2 + 1); + + p = orig_path; + d = new_path; + while ((c = *p++) != '\0') + { + if (c == ',') + *d++ = '\\'; + *d++ = c; + } + *d = 0; + + return new_path; +} + +char * +grub_util_guess_bios_drive (const char *orig_path) +{ + char *canon; + char *ptr; + canon = canonicalize_file_name (orig_path); + if (!canon) + return NULL; + ptr = strrchr (orig_path, '/'); + if (ptr) + ptr++; + else + ptr = canon; + if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("hd%d", num); + } + if (ptr[0] == 'f' && ptr[1] == 'd') + { + int num = atoi (ptr + 2); + free (canon); + return xasprintf ("fd%d", num); + } + free (canon); + return NULL; +} + +char * +grub_util_guess_efi_drive (const char *orig_path) +{ + char *canon; + char *ptr; + canon = canonicalize_file_name (orig_path); + if (!canon) + return NULL; + ptr = strrchr (orig_path, '/'); + if (ptr) + ptr++; + else + ptr = canon; + if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("hd%d", num); + } + if (ptr[0] == 'f' && ptr[1] == 'd') + { + int num = atoi (ptr + 2); + free (canon); + return xasprintf ("fd%d", num); + } + free (canon); + return NULL; +} + +char * +grub_util_guess_baremetal_drive (const char *orig_path) +{ + char *canon; + char *ptr; + canon = canonicalize_file_name (orig_path); + if (!canon) + return NULL; + ptr = strrchr (orig_path, '/'); + if (ptr) + ptr++; + else + ptr = canon; + if (ptr[0] == 'h' && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("ata%d", num); + } + if (ptr[0] == 's' && ptr[1] == 'd') + { + int num = ptr[2] - 'a'; + free (canon); + return xasprintf ("ahci%d", num); + } + free (canon); + return NULL; +} + +void +grub_util_fprint_full_disk_name (FILE *f, + const char *drive, grub_device_t dev) +{ + char *dname = escape_of_path (drive); + if (dev->disk->partition) + { + char *pname = grub_partition_get_name (dev->disk->partition); + fprintf (f, "%s,%s", dname, pname); + free (pname); + } + else + fprintf (f, "%s", dname); + free (dname); +} From 55e2c84fe32f49242b54fc90e0b6a5ade1dc1ab0 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 16 Nov 2013 21:11:01 +0100 Subject: [PATCH 14/55] * util/grub-install.c: Add new option --no-bootsector to skip installing of bootsector. Accept --grub-setup=/bin/true as backwards-compatible synonym. --- ChangeLog | 6 ++++++ util/grub-install.c | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46be8e6d8..0814b2b38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-11-16 Vladimir Serbinenko + + * util/grub-install.c: Add new option --no-bootsector to skip + installing of bootsector. Accept --grub-setup=/bin/true as + backwards-compatible synonym. + 2013-11-16 Andrey Borzenkov * util/grub-install.c (device_map_check_duplicates): Fix incorrect diff --git a/util/grub-install.c b/util/grub-install.c index 100f09379..454b7b847 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -67,6 +67,7 @@ static char * bootloader_id; static int have_load_cfg = 0; static FILE * load_cfg_f = NULL; static char *load_cfg; +static int install_bootsector = 1; enum { @@ -91,7 +92,8 @@ enum OPTION_DEBUG, OPTION_DEBUG_IMAGE, OPTION_NO_FLOPPY, - OPTION_DISK_MODULE + OPTION_DISK_MODULE, + OPTION_NO_BOOTSECTOR }; static int fs_probe = 1; @@ -110,9 +112,13 @@ argp_parser (int key, char *arg, struct argp_state *state) fs_probe = 0; return 0; + case OPTION_SETUP: + if (!grub_strstr (arg, "setup")) + install_bootsector = 0; + return 0; + /* Accept and ignore for compatibility. */ case OPTION_FONT: - case OPTION_SETUP: case OPTION_MKRELPATH: case OPTION_PROBE: case OPTION_EDITENV: @@ -170,6 +176,10 @@ argp_parser (int key, char *arg, struct argp_state *state) allow_floppy = 1; return 0; + case OPTION_NO_BOOTSECTOR: + install_bootsector = 0; + return 0; + case OPTION_DEBUG: verbosity++; return 0; @@ -224,6 +234,10 @@ static struct argp_option options[] = { {"no-nvram", OPTION_NO_NVRAM, 0, 0, N_("don't update the `boot-device' NVRAM variable. " "This option is only available on IEEE1275 targets."), 2}, + {"skip-fs-probe",'s',0, 0, + N_("do not probe for filesystems in DEVICE"), 0}, + {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0, + N_("do not install bootsector"), 0}, {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, @@ -235,9 +249,6 @@ static struct argp_option options[] = { N_("the ID of bootloader. This option is only available on EFI."), 2}, {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0, N_("use DIR as the EFI System Partition root."), 2}, - {"skip-fs-probe",'s',0, 0, - N_("do not probe for filesystems in DEVICE"), 0}, - {0, 0, 0, 0, 0, 0} }; @@ -1388,7 +1399,8 @@ main (int argc, char *argv[]) "boot.img"); grub_install_copy_file (boot_img_src, boot_img, 1); - grub_util_info ("grub_bios_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + grub_util_info ("%sgrub_bios_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + install_bootsector ? "" : "NOT RUNNING: ", allow_floppy ? "--allow-floppy " : "", verbosity ? "--verbose " : "", force ? "--force " : "", @@ -1398,9 +1410,10 @@ main (int argc, char *argv[]) install_device); /* Now perform the installation. */ - grub_util_bios_setup (platdir, "boot.img", "core.img", - install_drive, force, - fs_probe, allow_floppy); + if (install_bootsector) + grub_util_bios_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy); break; } case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: @@ -1412,7 +1425,8 @@ main (int argc, char *argv[]) "boot.img"); grub_install_copy_file (boot_img_src, boot_img, 1); - grub_util_info ("grub_sparc_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + grub_util_info ("%sgrub_sparc_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + install_bootsector ? "" : "NOT RUNNING: ", allow_floppy ? "--allow-floppy " : "", verbosity ? "--verbose " : "", force ? "--force " : "", @@ -1422,9 +1436,10 @@ main (int argc, char *argv[]) install_drive); /* Now perform the installation. */ - grub_util_sparc_setup (platdir, "boot.img", "core.img", - install_device, force, - fs_probe, allow_floppy); + if (install_bootsector) + grub_util_sparc_setup (platdir, "boot.img", "core.img", + install_device, force, + fs_probe, allow_floppy); break; } From d4d55b29e0ad7df8447f3ffebb15fa35d2e6a04b Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 00:54:40 +0100 Subject: [PATCH 15/55] * util/grub-install-common.c (platforms): Fix the order of entries and remove useless field val. --- ChangeLog | 5 +++++ util/grub-install-common.c | 39 +++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0814b2b38..3f891a84e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-17 Vladimir Serbinenko + + * util/grub-install-common.c (platforms): Fix the order of entries and + remove useless field val. + 2013-11-16 Vladimir Serbinenko * util/grub-install.c: Add new option --no-bootsector to skip diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 75a315d06..c60d2df4f 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -585,28 +585,27 @@ copy_locales (const char *dstd) static struct { - enum grub_install_plat val; const char *cpu; const char *platform; -} platforms[] = +} platforms[GRUB_INSTALL_PLATFORM_MAX] = { - { GRUB_INSTALL_PLATFORM_I386_PC, "i386", "pc" }, - { GRUB_INSTALL_PLATFORM_I386_EFI, "i386", "efi" }, - { GRUB_INSTALL_PLATFORM_I386_QEMU, "i386", "qemu" }, - { GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386", "coreboot" }, - { GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386", "multiboot" }, - { GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386", "ieee1275" }, - { GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64", "efi" }, - { GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel", "loongson" }, - { GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel", "qemu_mips" }, - { GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips", "qemu_mips" }, - { GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel", "arc" }, - { GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips", "arc" }, - { GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, "sparc64", "ieee1275" }, - { GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc", "ieee1275" }, - { GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64", "efi" }, - { GRUB_INSTALL_PLATFORM_ARM_EFI, "arm", "efi" }, - { GRUB_INSTALL_PLATFORM_ARM_UBOOT, "arm", "uboot" }, + [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, + [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, + [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, + [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, + [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, + [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, + [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, }; char * @@ -825,7 +824,7 @@ grub_install_get_target (const char *src) && strcmp (platforms[i].platform, pl) == 0) { free (fn); - return platforms[i].val; + return i; } grub_util_error (_("Unknown platform `%s-%s'"), c, pl); } From 889ebe922b50afd5241f6586f5656810972f4308 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 00:57:54 +0100 Subject: [PATCH 16/55] * tests/util/grub-shell.in: Use escc-ch-b on powerpc. This is missing counterpart of fixing the naming of escc ports. --- ChangeLog | 5 +++++ tests/util/grub-shell.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3f891a84e..6a8edf5d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-17 Vladimir Serbinenko + + * tests/util/grub-shell.in: Use escc-ch-b on powerpc. This is missing + counterpart of fixing the naming of escc ports. + 2013-11-17 Vladimir Serbinenko * util/grub-install-common.c (platforms): Fix the order of entries and diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 22277fbdf..ddd10d106 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -79,7 +79,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in boot=hd qemu=qemu-system-ppc console=console - serial_port=escc-ch-a + serial_port=escc-ch-b serial_null="-serial null" netbootext=elf ;; From 8df6eff6daf851f470e63ca598095629ee942faa Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 01:01:47 +0100 Subject: [PATCH 17/55] * include/grub/misc.h: Replace check for __sparc64__ with one for __sparc__ as __sparc64__ isn't actually defined. --- ChangeLog | 5 +++++ include/grub/misc.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6a8edf5d7..72b8bf873 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-17 Vladimir Serbinenko + + * include/grub/misc.h: Replace check for __sparc64__ with one for + __sparc__ as __sparc64__ isn't actually defined. + 2013-11-17 Vladimir Serbinenko * tests/util/grub-shell.in: Use escc-ch-b on powerpc. This is missing diff --git a/include/grub/misc.h b/include/grub/misc.h index 9c8faf274..3d7147797 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -465,7 +465,7 @@ EXPORT_FUNC (__umodsi3) (grub_uint32_t a, grub_uint32_t b); #endif -#if defined (__sparc64__) || defined (__powerpc__) +#if defined (__sparc__) || defined (__powerpc__) unsigned EXPORT_FUNC (__ctzdi2) (grub_uint64_t x); #define NEED_CTZDI2 1 From 3a129dba5966b2f07cebcf22edede7dd69b11533 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 02:01:21 +0100 Subject: [PATCH 18/55] * util/grub-install-common.c (grub_install_parse): Recognize --compress=none like shell script did. --- ChangeLog | 5 +++++ util/grub-install-common.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 72b8bf873..1fc953885 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-17 Vladimir Serbinenko + + * util/grub-install-common.c (grub_install_parse): Recognize + --compress=none like shell script did. + 2013-11-17 Vladimir Serbinenko * include/grub/misc.h: Replace check for __sparc64__ with one for diff --git a/util/grub-install-common.c b/util/grub-install-common.c index c60d2df4f..d29da380d 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -329,7 +329,8 @@ grub_install_parse (int key, char *arg) handle_install_list (&install_fonts, arg, 0); return 1; case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS: - if (strcmp (arg, "no") == 0) + if (strcmp (arg, "no") == 0 + || strcmp (arg, "none") == 0) { compress_func = NULL; return 1; From 66c00cb159bd2317ca8b9aeb9332cb75163f9ee9 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 02:03:03 +0100 Subject: [PATCH 19/55] * util/grub-mkrescue.c (main): Use right source file for bootinfo.txt. --- ChangeLog | 4 ++++ util/grub-mkrescue.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1fc953885..365aecc9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-17 Vladimir Serbinenko + + * util/grub-mkrescue.c (main): Use right source file for bootinfo.txt. + 2013-11-17 Vladimir Serbinenko * util/grub-install-common.c (grub_install_parse): Recognize diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index 0b8c39bcb..512aca8d2 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -679,7 +679,7 @@ main (int argc, char *argv[]) char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], "grub.chrp"); char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], - "grub.chrp"); + "bootinfo.txt"); char *bootx = grub_util_path_concat (2, core_services, "BootX"); char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp"); char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt"); From 6aa6077bcc38cd00a068ceb905dfe9ee7bd9c53c Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 02:05:45 +0100 Subject: [PATCH 20/55] * util/grub-mkrescue.c (main): Add trailing \n in .disk_label.contentDetails to be in line with previous shell script. --- ChangeLog | 5 +++++ util/grub-mkrescue.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 365aecc9d..813074e75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-17 Vladimir Serbinenko + + * util/grub-mkrescue.c (main): Add trailing \n in + .disk_label.contentDetails to be in line with previous shell script. + 2013-11-17 Vladimir Serbinenko * util/grub-mkrescue.c (main): Use right source file for bootinfo.txt. diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index 512aca8d2..df55f3dcf 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -583,7 +583,7 @@ main (int argc, char *argv[]) free (label); label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails"); f = grub_util_fopen (label_text, "wb"); - fprintf (f, "%s", label_string); + fprintf (f, "%s\n", label_string); fclose (f); free (label_string); free (label_text); From b80c2d6d4b0c3b79d102ef8921c15db3c8f2833a Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 02:09:15 +0100 Subject: [PATCH 21/55] * tests/core_compress_test.in: Use full arguments as grub-mkimage-extra now needs full arguments. --- ChangeLog | 5 +++++ tests/core_compress_test.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 813074e75..23011288e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-17 Vladimir Serbinenko + + * tests/core_compress_test.in: Use full arguments as grub-mkimage-extra + now needs full arguments. + 2013-11-17 Vladimir Serbinenko * util/grub-mkrescue.c (main): Add trailing \n in diff --git a/tests/core_compress_test.in b/tests/core_compress_test.in index f97c0240b..1003587cc 100644 --- a/tests/core_compress_test.in +++ b/tests/core_compress_test.in @@ -27,10 +27,10 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in esac -if [ "$(echo hello | "${grubshell}" --grub-mkimage-extra=-C --grub-mkimage-extra=xz)" != "Hello World" ]; then +if [ "$(echo hello | "${grubshell}" --grub-mkimage-extra=--compress=xz)" != "Hello World" ]; then exit 1 fi -if [ "$(echo hello | "${grubshell}" --grub-mkimage-extra=-C --grub-mkimage-extra=none)" != "Hello World" ]; then +if [ "$(echo hello | "${grubshell}" --grub-mkimage-extra=--compress=none)" != "Hello World" ]; then exit 1 fi From 0ab8e025c164d07f8e23ec2f6fd382489e4d6370 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 02:13:33 +0100 Subject: [PATCH 22/55] * grub-core/tests/cmdline_cat_test.c (cmdline_cat_test): Ignore errors of loading gfxterm as gfxterm is embed in kernel on some platforms. * grub-core/tests/gfxterm_menu.c (gfxterm_menu): Likewise. Load gfxmenu. --- ChangeLog | 7 +++++++ grub-core/tests/cmdline_cat_test.c | 1 + grub-core/tests/gfxterm_menu.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 23011288e..40fd400d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-11-17 Vladimir Serbinenko + + * grub-core/tests/cmdline_cat_test.c (cmdline_cat_test): Ignore errors + of loading gfxterm as gfxterm is embed in kernel on some platforms. + * grub-core/tests/gfxterm_menu.c (gfxterm_menu): Likewise. + Load gfxmenu. + 2013-11-17 Vladimir Serbinenko * tests/core_compress_test.in: Use full arguments as grub-mkimage-extra diff --git a/grub-core/tests/cmdline_cat_test.c b/grub-core/tests/cmdline_cat_test.c index 55e90a9d7..3337d34cb 100644 --- a/grub-core/tests/cmdline_cat_test.c +++ b/grub-core/tests/cmdline_cat_test.c @@ -74,6 +74,7 @@ cmdline_cat_test (void) unsigned i; grub_dl_load ("gfxterm"); + grub_errno = GRUB_ERR_NONE; if (grub_font_load ("unicode") == 0) { diff --git a/grub-core/tests/gfxterm_menu.c b/grub-core/tests/gfxterm_menu.c index 915875909..68531892f 100644 --- a/grub-core/tests/gfxterm_menu.c +++ b/grub-core/tests/gfxterm_menu.c @@ -101,6 +101,10 @@ gfxterm_menu (void) grub_dl_load ("gettext"); grub_dl_load ("gfxterm"); + grub_errno = GRUB_ERR_NONE; + + grub_dl_load ("gfxmenu"); + if (grub_font_load ("unicode") == 0) { grub_test_assert (0, "unicode font not found: %s", grub_errmsg); From 77dae919b6a6cc16d660171e61c9e0ba119c7b41 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 17 Nov 2013 02:16:21 +0100 Subject: [PATCH 23/55] * tests/grub_func_test.in: Increase memory reservation as on EFI we need to leave some memory to firmware. --- ChangeLog | 5 +++++ tests/grub_func_test.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 40fd400d6..8a6f0ed46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-17 Vladimir Serbinenko + + * tests/grub_func_test.in: Increase memory reservation as on EFI we need + to leave some memory to firmware. + 2013-11-17 Vladimir Serbinenko * grub-core/tests/cmdline_cat_test.c (cmdline_cat_test): Ignore errors diff --git a/tests/grub_func_test.in b/tests/grub_func_test.in index c039ffde0..cfb200cf9 100644 --- a/tests/grub_func_test.in +++ b/tests/grub_func_test.in @@ -4,7 +4,7 @@ set -e . "@builddir@/grub-core/modinfo.sh" # Increase memory as some of tests are high-resolution and need a lot of memory. -out=`echo all_functional_test | @builddir@/grub-shell --timeout=3600 --files="/boot/grub/fonts/unicode.pf2"="@builddir@/"unicode.pf2 --qemu-opts="-m 512"` +out=`echo all_functional_test | @builddir@/grub-shell --timeout=3600 --files="/boot/grub/fonts/unicode.pf2"="@builddir@/"unicode.pf2 --qemu-opts="-m 1G"` if [ "$(echo "$out" | tail -n 1)" != "ALL TESTS PASSED" ]; then echo "Functional test failure: $out" From 7d400406a77a61b04ae79194b630ada2a5019b92 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Sun, 17 Nov 2013 15:38:09 +0100 Subject: [PATCH 24/55] * grub-core/disk/uboot/ubootdisk.c: Include SCSI disks. --- ChangeLog | 4 ++++ grub-core/disk/uboot/ubootdisk.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8a6f0ed46..aa4f4cfc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-17 Ian Campbell + + * grub-core/disk/uboot/ubootdisk.c: Include SCSI disks. + 2013-11-17 Vladimir Serbinenko * tests/grub_func_test.in: Increase memory reservation as on EFI we need diff --git a/grub-core/disk/uboot/ubootdisk.c b/grub-core/disk/uboot/ubootdisk.c index f2c7a6acd..a5ce07a99 100644 --- a/grub-core/disk/uboot/ubootdisk.c +++ b/grub-core/disk/uboot/ubootdisk.c @@ -47,6 +47,7 @@ grub_ubootdisk_register (struct device_info *newdev) { case DT_STOR_IDE: case DT_STOR_SATA: + case DT_STOR_SCSI: case DT_STOR_MMC: case DT_STOR_USB: /* hd */ From 44ce3a93b67efc2dde802d861d110fa79305f385 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 01:49:14 +0100 Subject: [PATCH 25/55] * include/grub/mips/setjmp.h (grub_jmp_buf): Fix buffer size. setjmp.S uses 12 entries but buffer is declared with only 11 entries. --- ChangeLog | 6 ++++++ include/grub/mips/setjmp.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aa4f4cfc8..cfb9fb30b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-11-18 Vladimir Serbinenko + + * include/grub/mips/setjmp.h (grub_jmp_buf): Fix buffer size. + + setjmp.S uses 12 entries but buffer is declared with only 11 entries. + 2013-11-17 Ian Campbell * grub-core/disk/uboot/ubootdisk.c: Include SCSI disks. diff --git a/include/grub/mips/setjmp.h b/include/grub/mips/setjmp.h index 5ce45f508..a99dde9ef 100644 --- a/include/grub/mips/setjmp.h +++ b/include/grub/mips/setjmp.h @@ -19,7 +19,7 @@ #ifndef GRUB_SETJMP_CPU_HEADER #define GRUB_SETJMP_CPU_HEADER 1 -typedef unsigned long grub_jmp_buf[11]; +typedef unsigned long grub_jmp_buf[12]; int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); From 4336b5d85ef2b5d53fd7e54cae5cb0674b35b7e0 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 02:03:36 +0100 Subject: [PATCH 26/55] * util/grub-mkrescue.c (make_image_fwdisk_abs): Insert all partmap modules to be in line with make_image_abs. --- ChangeLog | 5 +++++ util/grub-mkrescue.c | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cfb9fb30b..050f0b70d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * util/grub-mkrescue.c (make_image_fwdisk_abs): Insert all partmap + modules to be in line with make_image_abs. + 2013-11-18 Vladimir Serbinenko * include/grub/mips/setjmp.h (grub_jmp_buf): Fix buffer size. diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index df55f3dcf..3b6b742bb 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -290,12 +290,24 @@ make_image_fwdisk_abs (enum grub_install_plat plat, const char *mkimage_target, const char *output) { + char *load_cfg; + FILE *load_cfg_f; + if (!source_dirs[plat]) return; + grub_util_info (N_("enabling %s support ..."), + mkimage_target); + + load_cfg = grub_util_make_temporary_file (); + + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + write_part (load_cfg_f, source_dirs[plat]); + fclose (load_cfg_f); + grub_install_push_module ("iso9660"); grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output, - 0, 0, mkimage_target, 0, + 0, load_cfg, mkimage_target, 0, GRUB_COMPRESSION_AUTO); grub_install_pop_module (); } From 59c943ecf6bf26a3ef07c9ebd85a21f9402eeee0 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 02:35:32 +0100 Subject: [PATCH 27/55] * grub-core/lib/powerpc/setjmp.S (grub_setjmp): Save r31. (grub_longjmp): Restore r31. * include/grub/powerpc/setjmp.h (grub_jmp_buf): Reserve space for r31. --- ChangeLog | 6 ++++++ grub-core/lib/powerpc/setjmp.S | 10 ++++++---- include/grub/powerpc/setjmp.h | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 050f0b70d..49d75e070 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/lib/powerpc/setjmp.S (grub_setjmp): Save r31. + (grub_longjmp): Restore r31. + * include/grub/powerpc/setjmp.h (grub_jmp_buf): Reserve space for r31. + 2013-11-18 Vladimir Serbinenko * util/grub-mkrescue.c (make_image_fwdisk_abs): Insert all partmap diff --git a/grub-core/lib/powerpc/setjmp.S b/grub-core/lib/powerpc/setjmp.S index c301a7b07..716b563fa 100644 --- a/grub-core/lib/powerpc/setjmp.S +++ b/grub-core/lib/powerpc/setjmp.S @@ -47,10 +47,11 @@ FUNCTION(grub_setjmp) stw 28, 60(3) stw 29, 64(3) stw 30, 68(3) + stw 31, 72(3) mflr 4 - stw 4, 72(3) - mfcr 4 stw 4, 76(3) + mfcr 4 + stw 4, 80(3) li 3, 0 blr @@ -76,9 +77,10 @@ FUNCTION(grub_longjmp) lwz 28, 60(3) lwz 29, 64(3) lwz 30, 68(3) - lwz 5, 72(3) - mtlr 5 + lwz 31, 72(3) lwz 5, 76(3) + mtlr 5 + lwz 5, 80(3) mtcr 5 mr. 3, 4 bne 1f diff --git a/include/grub/powerpc/setjmp.h b/include/grub/powerpc/setjmp.h index 9beddfdb2..7c2d184fa 100644 --- a/include/grub/powerpc/setjmp.h +++ b/include/grub/powerpc/setjmp.h @@ -19,7 +19,7 @@ #ifndef GRUB_SETJMP_CPU_HEADER #define GRUB_SETJMP_CPU_HEADER 1 -typedef unsigned long grub_jmp_buf[20]; +typedef unsigned long grub_jmp_buf[21]; int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); From da93d6753b6a914708d042b08768599873d3f6c7 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 02:37:46 +0100 Subject: [PATCH 28/55] * grub-core/commands/legacycfg.c (grub_legacy_check_md5_password): Plug memory leak. --- ChangeLog | 5 +++++ grub-core/commands/legacycfg.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 49d75e070..57e82f05c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/commands/legacycfg.c (grub_legacy_check_md5_password): Plug + memory leak. + 2013-11-18 Vladimir Serbinenko * grub-core/lib/powerpc/setjmp.S (grub_setjmp): Save r31. diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 4443341b4..f429a5d1b 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -735,6 +735,7 @@ grub_legacy_check_md5_password (int argc, char **args, char *entered) { struct legacy_md5_password *pw = NULL; + int ret; if (args[0][0] != '-' || args[0][1] != '-') { @@ -751,7 +752,9 @@ grub_legacy_check_md5_password (int argc, char **args, if (!pw) return 0; - return check_password_md5_real (entered, pw); + ret = check_password_md5_real (entered, pw); + grub_free (pw); + return ret; } static grub_err_t From 7bbb60cfbde10543bc053c79ab82db253c4e31fe Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 02:40:17 +0100 Subject: [PATCH 29/55] * grub-core/commands/verify.c (free_pk): Plug memory leak. (grub_load_public_key): Likewise. (grub_verify_signature_real): Likewise. (grub_cmd_verify_signature): Likewise. --- ChangeLog | 7 +++++++ grub-core/commands/verify.c | 30 +++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 57e82f05c..beac10772 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/commands/verify.c (free_pk): Plug memory leak. + (grub_load_public_key): Likewise. + (grub_verify_signature_real): Likewise. + (grub_cmd_verify_signature): Likewise. + 2013-11-18 Vladimir Serbinenko * grub-core/commands/legacycfg.c (grub_legacy_check_md5_password): Plug diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c index 3e61c2257..dbe7e83c0 100644 --- a/grub-core/commands/verify.c +++ b/grub-core/commands/verify.c @@ -192,6 +192,10 @@ free_pk (struct grub_public_key *pk) struct grub_public_subkey *nsk, *sk; for (sk = pk->subkeys; sk; sk = nsk) { + grub_size_t i; + for (i = 0; i < ARRAY_SIZE (sk->mpis); i++) + if (sk->mpis[i]) + gcry_mpi_release (sk->mpis[i]); nsk = sk->next; grub_free (sk); } @@ -244,6 +248,7 @@ grub_load_public_key (grub_file_t f) if (type == 0xff) { grub_free (fingerprint_context); + grub_free (buffer); return ret; } @@ -631,6 +636,9 @@ grub_verify_signature_real (char *buf, grub_size_t size, if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0)) goto fail; + grub_free (context); + grub_free (readbuf); + return GRUB_ERR_NONE; fail: @@ -736,8 +744,8 @@ static grub_err_t grub_cmd_verify_signature (grub_extcmd_context_t ctxt, int argc, char **args) { - grub_file_t f, sig; - grub_err_t err; + grub_file_t f = NULL, sig = NULL; + grub_err_t err = GRUB_ERR_NONE; struct grub_public_key *pk = NULL; grub_dprintf ("crypt", "alive\n"); @@ -768,19 +776,27 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt, grub_file_filter_disable_all (); f = grub_file_open (args[0]); if (!f) - return grub_errno; + { + err = grub_errno; + goto fail; + } grub_file_filter_disable_all (); sig = grub_file_open (args[1]); if (!sig) { - grub_file_close (f); - return grub_errno; + err = grub_errno; + goto fail; } err = grub_verify_signature (f, sig, pk); - grub_file_close (f); - grub_file_close (sig); + fail: + if (sig) + grub_file_close (sig); + if (f) + grub_file_close (f); + if (pk) + free_pk (pk); return err; } From 33d02a42d64cf06cada1c389e5abba4b9d196cc5 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 02:41:42 +0100 Subject: [PATCH 30/55] * grub-core/kern/file.c (grub_file_open): Free file->name on failure. (grub_file_close): Free file->name. --- ChangeLog | 5 +++++ grub-core/kern/file.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index beac10772..ea7f15c33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/kern/file.c (grub_file_open): Free file->name on failure. + (grub_file_close): Free file->name. + 2013-11-18 Vladimir Serbinenko * grub-core/commands/verify.c (free_pk): Plug memory leak. diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c index ea1817a41..24da12bb9 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -87,9 +87,6 @@ grub_file_open (const char *name) if (! file) goto fail; - file->name = grub_strdup (name); - grub_errno = GRUB_ERR_NONE; - file->device = device; if (device->disk && file_name[0] != '/') @@ -105,6 +102,9 @@ grub_file_open (const char *name) if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE) goto fail; + file->name = grub_strdup (name); + grub_errno = GRUB_ERR_NONE; + for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters_enabled); filter++) if (grub_file_filters_enabled[filter]) @@ -187,6 +187,7 @@ grub_file_close (grub_file_t file) if (file->device) grub_device_close (file->device); + grub_free (file->name); grub_free (file); return grub_errno; } From 35d4761ce2b154523c3c43b6331b0ab537b7a5e2 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 02:43:29 +0100 Subject: [PATCH 31/55] * grub-core/normal/cmdline.c (grub_cmdline_get): Plug memory leak. --- ChangeLog | 4 ++++ grub-core/normal/cmdline.c | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea7f15c33..c93e3d103 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/normal/cmdline.c (grub_cmdline_get): Plug memory leak. + 2013-11-18 Vladimir Serbinenko * grub-core/kern/file.c (grub_file_open): Free file->name on failure. diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index 2ef500ffb..204d15a4b 100644 --- a/grub-core/normal/cmdline.c +++ b/grub-core/normal/cmdline.c @@ -379,12 +379,18 @@ grub_cmdline_get (const char *prompt_translated) cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms); if (!cl_terms) - return 0; + { + grub_free (buf); + return 0; + } cl_term_cur = cl_terms; unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); if (!unicode_msg) - return 0;; + { + grub_free (buf); + return 0; + } msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len - 1, (grub_uint8_t *) prompt_translated, -1, 0); unicode_msg[msg_len++] = ' '; @@ -621,6 +627,7 @@ grub_cmdline_get (const char *prompt_translated) case '\e': grub_free (cl_terms); + grub_free (buf); return 0; case '\b': From 04f39f6df8fed3db08c6333d3b557d15bfe3d5a2 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 02:45:25 +0100 Subject: [PATCH 32/55] * grub-core/lib/relocator.c (grub_mm_check_real): Accept const char * as file argument. --- ChangeLog | 5 +++++ grub-core/lib/relocator.c | 2 +- include/grub/mm.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c93e3d103..2ff66607f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/lib/relocator.c (grub_mm_check_real): Accept const char * + as file argument. + 2013-11-18 Vladimir Serbinenko * grub-core/normal/cmdline.c (grub_cmdline_get): Plug memory leak. diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index c86c5e886..9f9770bc4 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -1618,7 +1618,7 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, } void -grub_mm_check_real (char *file, int line) +grub_mm_check_real (const char *file, int line) { grub_mm_region_t r; grub_mm_header_t p, pa; diff --git a/include/grub/mm.h b/include/grub/mm.h index 047006944..c6660af71 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -35,7 +35,7 @@ void EXPORT_FUNC(grub_free) (void *ptr); void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); -void grub_mm_check_real (char *file, int line); +void grub_mm_check_real (const char *file, int line); #define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__); /* For debugging. */ From 6f1bc8bc0f1c6d911d162e2930450fb1dd5abb99 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 04:32:33 +0100 Subject: [PATCH 33/55] On i386-ieee1275 we run in paged mode. So we need to explicitly map the devices before accessing them. --- ChangeLog | 5 ++++ grub-core/Makefile.core.def | 1 + grub-core/bus/i386/ieee1275/pci.c | 42 +++++++++++++++++++++++++++++++ include/grub/i386/pci.h | 16 ++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 grub-core/bus/i386/ieee1275/pci.c diff --git a/ChangeLog b/ChangeLog index 2ff66607f..7f1cf0e53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + On i386-ieee1275 we run in paged mode. So we need to explicitly map + the devices before accessing them. + 2013-11-18 Vladimir Serbinenko * grub-core/lib/relocator.c (grub_mm_check_real): Accept const char * diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 4fff57f16..5cd84b183 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -563,6 +563,7 @@ module = { module = { name = pci; common = bus/pci.c; + i386_ieee1275 = bus/i386/ieee1275/pci.c; enable = i386_pc; enable = i386_ieee1275; diff --git a/grub-core/bus/i386/ieee1275/pci.c b/grub-core/bus/i386/ieee1275/pci.c new file mode 100644 index 000000000..1fd3b5610 --- /dev/null +++ b/grub-core/bus/i386/ieee1275/pci.c @@ -0,0 +1,42 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 + +volatile void * +grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), + grub_addr_t base, + grub_size_t size) +{ + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_REAL_MODE)) + return (volatile void *) base; + if (grub_ieee1275_map (base, base, size, 7)) + grub_fatal ("couldn't map 0x%lx", base); + return (volatile void *) base; +} + +void +grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), + volatile void *mem __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index 795dec58b..dffeb5695 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -70,6 +70,8 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); } +#ifndef GRUB_MACHINE_IEEE1275 + static inline volatile void * grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), grub_addr_t base, @@ -85,5 +87,19 @@ grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), { } +#else + +volatile void * +grub_pci_device_map_range (grub_pci_device_t dev, + grub_addr_t base, + grub_size_t size); + +void +grub_pci_device_unmap_range (grub_pci_device_t dev, + volatile void *mem, + grub_size_t size); + +#endif + #endif /* GRUB_CPU_PCI_H */ From 2df8f43d3e0457c0f48df754e6b7ddfb44d5f3bc Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 10:01:36 +0100 Subject: [PATCH 34/55] * grub-core/lib/sparc64/setjmp.S: Force spilling of current window. --- ChangeLog | 4 ++++ grub-core/lib/sparc64/setjmp.S | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7f1cf0e53..8f4de761a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/lib/sparc64/setjmp.S: Force spilling of current window. + 2013-11-18 Vladimir Serbinenko On i386-ieee1275 we run in paged mode. So we need to explicitly map diff --git a/grub-core/lib/sparc64/setjmp.S b/grub-core/lib/sparc64/setjmp.S index ec9c53057..6c11bdda0 100644 --- a/grub-core/lib/sparc64/setjmp.S +++ b/grub-core/lib/sparc64/setjmp.S @@ -41,7 +41,11 @@ FUNCTION(grub_setjmp) FUNCTION(grub_longjmp) ldx [%o0 + 0x10], %g1 movrz %o1, 1, %o1 + + save %sp, -64, %sp flushw + restore + ldx [%o0 + 0x00], %o7 ldx [%o0 + 0x08], %fp sub %fp, 192, %sp From a284320e1e0e44773960b76b9e0ce23c5ea362b5 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 11:38:00 +0100 Subject: [PATCH 35/55] Fix handling of install lists. --- ChangeLog | 4 ++++ util/grub-install-common.c | 15 +++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8f4de761a..8e286bf76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-18 Vladimir Serbinenko + + Fix handling of install lists. + 2013-11-18 Vladimir Serbinenko * grub-core/lib/sparc64/setjmp.S: Force spilling of current window. diff --git a/util/grub-install-common.c b/util/grub-install-common.c index d29da380d..bdb81a72d 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -271,6 +271,7 @@ handle_install_list (struct install_list *il, const char *val, } il->n_alloc = il->n_entries + 1; il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); + ptr = val; for (ce = il->entries; ; ce++) { const char *bptr; @@ -284,7 +285,6 @@ handle_install_list (struct install_list *il, const char *val, *ce = xmalloc (ptr - bptr + 1); memcpy (*ce, bptr, ptr - bptr); (*ce)[ptr - bptr] = '\0'; - ce++; } *ce = NULL; } @@ -662,10 +662,17 @@ grub_install_copy_files (const char *src, install_modules.entries); for (p = path_list; p; p = p->next) { - char *srcf = grub_util_path_concat_ext (2, src, p->name, ".mo"); - char *dstf = grub_util_path_concat_ext (2, dst, p->name, ".mo"); + const char *srcf = p->name; + const char *dir; + char *dstf; + + dir = grub_strrchr (srcf, '/'); + if (dir) + dir++; + else + dir = srcf; + dstf = grub_util_path_concat (2, dst, dir); grub_install_compress_file (srcf, dstf, 1); - free (srcf); free (dstf); } } From 4bf703206dd72914cc697232e76e1a87a7ec74a0 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 11:45:55 +0100 Subject: [PATCH 36/55] * grub-core/tests/cmdline_cat_test.c: Don't reload unifont if it's already loaded. This saves memory needed for tests, --- ChangeLog | 5 +++++ grub-core/tests/cmdline_cat_test.c | 10 +++++++++- grub-core/tests/gfxterm_menu.c | 11 ++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e286bf76..e1989f780 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/tests/cmdline_cat_test.c: Don't reload unifont if it's + already loaded. This saves memory needed for tests, + 2013-11-18 Vladimir Serbinenko Fix handling of install lists. diff --git a/grub-core/tests/cmdline_cat_test.c b/grub-core/tests/cmdline_cat_test.c index 3337d34cb..c3de5c464 100644 --- a/grub-core/tests/cmdline_cat_test.c +++ b/grub-core/tests/cmdline_cat_test.c @@ -66,17 +66,25 @@ struct grub_procfs_entry test_txt = .get_contents = get_test_txt }; +#define FONT_NAME "Unknown Regular 16" /* Functional test main method. */ static void cmdline_cat_test (void) { unsigned i; + grub_font_t font; grub_dl_load ("gfxterm"); grub_errno = GRUB_ERR_NONE; - if (grub_font_load ("unicode") == 0) + font = grub_font_get (FONT_NAME); + if (font && grub_strcmp (font->name, FONT_NAME) != 0) + font = 0; + if (!font) + font = grub_font_load ("unicode"); + + if (!font) { grub_test_assert (0, "unicode font not found: %s", grub_errmsg); return; diff --git a/grub-core/tests/gfxterm_menu.c b/grub-core/tests/gfxterm_menu.c index 68531892f..879fbc003 100644 --- a/grub-core/tests/gfxterm_menu.c +++ b/grub-core/tests/gfxterm_menu.c @@ -91,12 +91,15 @@ struct { "gfxterm_high", "menu_color_highlight", "blue/red" }, }; +#define FONT_NAME "Unknown Regular 16" /* Functional test main method. */ static void gfxterm_menu (void) { unsigned i, j; + grub_font_t font; + grub_dl_load ("png"); grub_dl_load ("gettext"); grub_dl_load ("gfxterm"); @@ -105,7 +108,13 @@ gfxterm_menu (void) grub_dl_load ("gfxmenu"); - if (grub_font_load ("unicode") == 0) + font = grub_font_get (FONT_NAME); + if (font && grub_strcmp (font->name, FONT_NAME) != 0) + font = 0; + if (!font) + font = grub_font_load ("unicode"); + + if (!font) { grub_test_assert (0, "unicode font not found: %s", grub_errmsg); return; From f8b4c3b6b3a9633faa2d8240b6b4d62259caae5b Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 11:48:07 +0100 Subject: [PATCH 37/55] * grub-core/tests/gfxterm_menu.c: Skip high-resolution tests on low-memory platforms where we don't have enough memory for them. * grub-core/tests/videotest_checksum.c: Likewise. --- ChangeLog | 6 ++++++ grub-core/tests/gfxterm_menu.c | 11 ++++++++++- grub-core/tests/videotest_checksum.c | 17 ++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1989f780..05d25e958 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/tests/gfxterm_menu.c: Skip high-resolution tests on + low-memory platforms where we don't have enough memory for them. + * grub-core/tests/videotest_checksum.c: Likewise. + 2013-11-18 Vladimir Serbinenko * grub-core/tests/cmdline_cat_test.c: Don't reload unifont if it's diff --git a/grub-core/tests/gfxterm_menu.c b/grub-core/tests/gfxterm_menu.c index 879fbc003..8f63dc27a 100644 --- a/grub-core/tests/gfxterm_menu.c +++ b/grub-core/tests/gfxterm_menu.c @@ -125,7 +125,16 @@ gfxterm_menu (void) for (j = 0; j < ARRAY_SIZE (tests); j++) for (i = 0; i < GRUB_TEST_VIDEO_SMALL_N_MODES; i++) { - grub_uint64_t start = grub_get_time_ms (); + grub_uint64_t start; + +#if defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_IEEE1275) + if (grub_test_video_modes[i].width > 1024) + continue; + if (grub_strcmp (tests[j].name, "gfxmenu") == 0 + && grub_test_video_modes[i].width > 800) + continue; +#endif + start = grub_get_time_ms (); grub_video_capture_start (&grub_test_video_modes[i], grub_video_fbstd_colors, diff --git a/grub-core/tests/videotest_checksum.c b/grub-core/tests/videotest_checksum.c index ee7058f51..f120496b6 100644 --- a/grub-core/tests/videotest_checksum.c +++ b/grub-core/tests/videotest_checksum.c @@ -40,9 +40,20 @@ videotest_checksum (void) for (i = 0; i < ARRAY_SIZE (grub_test_video_modes); i++) { - grub_video_capture_start (&grub_test_video_modes[i], - grub_video_fbstd_colors, - grub_test_video_modes[i].number_of_colors); + grub_err_t err; +#if defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_IEEE1275) + if (grub_test_video_modes[i].width > 1024) + continue; +#endif + err = grub_video_capture_start (&grub_test_video_modes[i], + grub_video_fbstd_colors, + grub_test_video_modes[i].number_of_colors); + if (err) + { + grub_test_assert (0, "can't start capture: %s", grub_errmsg); + grub_print_error (); + continue; + } grub_terminal_input_fake_sequence ((int []) { '\n' }, 1); grub_video_checksum ("videotest"); From 256ee7ac6a2ec92bc8b9a2c7fb27d9db616b8379 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 11:51:46 +0100 Subject: [PATCH 38/55] * tests/util/grub-shell.in: For powerpc tests put the CD-ROM as primary master since with some combinations of qemu and firmware only primary IDE channel is available. --- ChangeLog | 6 ++++++ tests/util/grub-shell.in | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05d25e958..821a6396c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-11-18 Vladimir Serbinenko + + * tests/util/grub-shell.in: For powerpc tests put the CD-ROM as primary + master since with some combinations of qemu and firmware only primary + IDE channel is available. + 2013-11-18 Vladimir Serbinenko * grub-core/tests/gfxterm_menu.c: Skip high-resolution tests on diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index ddd10d106..0abdf1794 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -354,39 +354,43 @@ if [ x$boot != xnet ] && [ x$boot != xemu ]; then fi if [ x$boot = xhd ]; then if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mips-arc ]; then - device=hdb + device="hdb " else - device=hda + device="hda " fi bootdev="-boot c" fi if [ x$boot = xcd ]; then - device=cdrom + if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ]; then + device="-drive if=ide,media=cdrom,file=" + else + device="cdrom " + fi bootdev="-boot d" fi if [ x$boot = xfd ]; then - device=fda + device="fda " bootdev="-boot a" fi if [ x$boot = xqemu ]; then bootdev="-bios ${rom_directory}/qemu.img" - device=cdrom + device="cdrom " fi if [ x$boot = xmipsel_qemu ]; then bootdev="-kernel ${rom_directory}/mipsel-qemu_mips.elf" - device=cdrom + device="cdrom " fi if [ x$boot = xmipsel_fulong2e ]; then bootdev="-kernel ${rom_directory}/mipsel-loongson.elf -append machtype=lemote-fuloong-2e" - device=cdrom + device="cdrom " fi if [ x$boot = xmips_qemu ]; then bootdev="-kernel ${rom_directory}/mips-qemu_mips.elf" - device=cdrom + device="cdrom " fi if [ x$boot = xcoreboot ]; then @@ -394,7 +398,7 @@ if [ x$boot = xcoreboot ]; then cp "${GRUB_COREBOOT_ROM}" "${imgfile}" "${GRUB_CBFSTOOL}" "${imgfile}" add-payload "${rom_directory}/coreboot.elf" fallback/payload bootdev="-bios ${imgfile}" - device=cdrom + device="cdrom " test -z "$debug" || echo "Coreboot image: ${imgfile}" >&2 fi @@ -435,7 +439,7 @@ elif [ x$boot = xemu ]; then @builddir@/grub-core/grub-emu -m "$device_map" -d "$grubdir" | tr -d "\r" | do_trim rm -rf "$grubdir" else - timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device} ${isofile} ${bootdev} | cat | tr -d "\r" | do_trim + timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} | cat | tr -d "\r" | do_trim fi if [ x$boot = xcoreboot ]; then test -n "$debug" || rm -f "${imgfile}" From 3bf4088b8b5a6acba59babe829d4f4bc18fc3e7a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 18 Nov 2013 12:27:44 +0000 Subject: [PATCH 39/55] * grub-core/osdep/unix/hostdisk.c (grub_util_make_temporary_file): Handle errors from mkstemp. (grub_util_make_temporary_dir): Handle errors from mkdtemp. --- ChangeLog | 6 ++++++ grub-core/osdep/unix/hostdisk.c | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e286bf76..409fc70ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-11-18 Colin Watson + + * grub-core/osdep/unix/hostdisk.c (grub_util_make_temporary_file): + Handle errors from mkstemp. + (grub_util_make_temporary_dir): Handle errors from mkdtemp. + 2013-11-18 Vladimir Serbinenko Fix handling of install lists. diff --git a/grub-core/osdep/unix/hostdisk.c b/grub-core/osdep/unix/hostdisk.c index 1ca1abbfb..78d4adb71 100644 --- a/grub-core/osdep/unix/hostdisk.c +++ b/grub-core/osdep/unix/hostdisk.c @@ -281,7 +281,8 @@ grub_util_make_temporary_file (void) memcpy (tmp, t, tl); memcpy (tmp + tl, "/grub.XXXXXX", sizeof ("/grub.XXXXXX")); - mkstemp (tmp); + if (mkstemp (tmp) == -1) + grub_util_error (_("cannot make temporary file: %s"), strerror (errno)); return tmp; } @@ -298,7 +299,9 @@ grub_util_make_temporary_dir (void) memcpy (tmp, t, tl); memcpy (tmp + tl, "/grub.XXXXXX", sizeof ("/grub.XXXXXX")); - mkdtemp (tmp); + if (!mkdtemp (tmp)) + grub_util_error (_("cannot make temporary directory: %s"), + strerror (errno)); return tmp; } From 5e3cb8a7479c37a68b0e1ae02fff7ba5be4ff711 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 14:35:18 +0100 Subject: [PATCH 40/55] * grub-core/term/terminfo.c (grub_cmd_terminfo): Fix a typo to make -g work again. --- ChangeLog | 5 +++++ grub-core/term/terminfo.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 821a6396c..65f1a421c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/term/terminfo.c (grub_cmd_terminfo): Fix a typo to make -g + work again. + 2013-11-18 Vladimir Serbinenko * tests/util/grub-shell.in: For powerpc tests put the CD-ROM as primary diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 0bb355277..3d48b198f 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -748,8 +748,8 @@ grub_cmd_terminfo (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_terminfo_output_state *data = (struct grub_terminfo_output_state *) cur->data; - data->pos.x = w; - data->pos.y = h; + data->size.x = w; + data->size.y = h; } if (argc == 1) From 96adefdb122144aeec54cea5f064b7c77b774c39 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 14:36:31 +0100 Subject: [PATCH 41/55] * util/grub-mkrescue.c (main): Fix a typo to make yeeloong part work again. --- ChangeLog | 5 +++++ util/grub-mkrescue.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 65f1a421c..ae8f24f14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * util/grub-mkrescue.c (main): Fix a typo to make yeeloong part + work again. + 2013-11-18 Vladimir Serbinenko * grub-core/term/terminfo.c (grub_cmd_terminfo): Fix a typo to make -g diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index 3b6b742bb..5eec03747 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -769,7 +769,7 @@ main (int argc, char *argv[]) make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf", GRUB_COMPRESSION_XZ); make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin", GRUB_COMPRESSION_XZ); - make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fulong2f-flash", "mipsel-fuloong2f.bin", GRUB_COMPRESSION_XZ); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin", GRUB_COMPRESSION_XZ); make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf", GRUB_COMPRESSION_AUTO); From ea7c1a7d90cb21772ba6a1e04dd6507f54dab7fd Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 14:38:31 +0100 Subject: [PATCH 42/55] * grub-core/tests/videotest_checksum.c: Don't reload unifont if it's already loaded. This saves memory needed for tests, --- ChangeLog | 5 +++++ grub-core/tests/videotest_checksum.c | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ae8f24f14..b38485d0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/tests/videotest_checksum.c: Don't reload unifont if it's + already loaded. This saves memory needed for tests, + 2013-11-18 Vladimir Serbinenko * util/grub-mkrescue.c (main): Fix a typo to make yeeloong part diff --git a/grub-core/tests/videotest_checksum.c b/grub-core/tests/videotest_checksum.c index f120496b6..a4bff5ed8 100644 --- a/grub-core/tests/videotest_checksum.c +++ b/grub-core/tests/videotest_checksum.c @@ -26,13 +26,22 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#define FONT_NAME "Unknown Regular 16" + /* Functional test main method. */ static void videotest_checksum (void) { unsigned i; + grub_font_t font; - if (grub_font_load ("unicode") == 0) + font = grub_font_get (FONT_NAME); + if (font && grub_strcmp (font->name, FONT_NAME) != 0) + font = 0; + if (!font) + font = grub_font_load ("unicode"); + + if (!font) { grub_test_assert (0, "unicode font not found: %s", grub_errmsg); return; From 35c2851cc117ac07076b513a5936fe514d4fe154 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 14:40:41 +0100 Subject: [PATCH 43/55] * tests/util/grub-shell.in: Use -cdrom and don't force cdrom on primary master on pseries. --- ChangeLog | 5 +++++ tests/util/grub-shell.in | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b38485d0b..959db45df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * tests/util/grub-shell.in: Use -cdrom and don't force cdrom + on primary master on pseries. + 2013-11-18 Vladimir Serbinenko * grub-core/tests/videotest_checksum.c: Don't reload unifont if it's diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 0abdf1794..b0081cb7f 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -211,6 +211,7 @@ for option in "$@"; do serial_null= qemuopts="$qemuopts -M pseries -no-reboot" trim=1 + pseries=y ;; --qemu-opts=*) qs=`echo "$option" | sed -e 's/--qemu-opts=//'` @@ -361,7 +362,7 @@ if [ x$boot = xhd ]; then bootdev="-boot c" fi if [ x$boot = xcd ]; then - if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ]; then + if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ] && [ x$pseries != xy ] ; then device="-drive if=ide,media=cdrom,file=" else device="cdrom " From 1e8e2e78a599af9504847aa86ed37bb06be1ee9d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 18 Nov 2013 14:02:11 +0000 Subject: [PATCH 44/55] * tests/util/grub-shell.in: Don't fail on emu platform if po/*.gmo files have not been built. --- ChangeLog | 5 +++++ tests/util/grub-shell.in | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fec4dc731..2c43f6a9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Colin Watson + + * tests/util/grub-shell.in: Don't fail on emu platform if po/*.gmo + files have not been built. + 2013-11-18 Colin Watson * grub-core/osdep/unix/hostdisk.c (grub_util_make_temporary_file): diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index b0081cb7f..b3632a883 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -434,7 +434,11 @@ elif [ x$boot = xemu ]; then mkdir -p "$grubdir/locale" cp "@builddir@/"unicode.pf2 "$grubdir/fonts/unicode.pf2" cp -R "@srcdir@/themes/starfield" "$grubdir/themes/starfield" - cp -R "@srcdir@/po/"*.gmo "$grubdir/locale/" + for file in "@srcdir@/po/"*.gmo; do + if [ -f "$file" ]; then + cp "$file" "$grubdir/locale/" + fi + done cp "${cfgfile}" "$grubdir/grub.cfg" cp "${source}" "$grubdir/testcase.cfg" @builddir@/grub-core/grub-emu -m "$device_map" -d "$grubdir" | tr -d "\r" | do_trim From b40ce6518056e77c1e3aa2f8366a1944832b055f Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 15:59:55 +0100 Subject: [PATCH 45/55] * util/grub-install-common.c (grub_install_copy_files): Fix module destination directory. --- ChangeLog | 5 +++++ util/grub-install-common.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fec4dc731..ff2c821e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * util/grub-install-common.c (grub_install_copy_files): Fix module + destination directory. + 2013-11-18 Colin Watson * grub-core/osdep/unix/hostdisk.c (grub_util_make_temporary_file): diff --git a/util/grub-install-common.c b/util/grub-install-common.c index bdb81a72d..0bc7ea3ae 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -671,7 +671,7 @@ grub_install_copy_files (const char *src, dir++; else dir = srcf; - dstf = grub_util_path_concat (2, dst, dir); + dstf = grub_util_path_concat (2, dst_platform, dir); grub_install_compress_file (srcf, dstf, 1); free (dstf); } From b7526e7806dc7d81b809ec093f9256024231e8b0 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 16:05:47 +0100 Subject: [PATCH 46/55] * Makefile.am (default_payload.elf): Add pata to loaded modules. Load config file from (cbfsdisk)/etc/grub.cfg. --- ChangeLog | 5 +++++ Makefile.am | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ff2c821e3..68694c7bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * Makefile.am (default_payload.elf): Add pata to loaded modules. + Load config file from (cbfsdisk)/etc/grub.cfg. + 2013-11-18 Vladimir Serbinenko * util/grub-install-common.c (grub_install_copy_files): Fix module diff --git a/Makefile.am b/Makefile.am index 114c20045..506325693 100644 --- a/Makefile.am +++ b/Makefile.am @@ -394,7 +394,7 @@ bootcheck: $(BOOTCHECKS) if COND_i386_coreboot default_payload.elf: grub-mkstandalone grub-mkimage - pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump setpci lsacpi chain' --fonts= --themes= --locales= -d grub-core/ + pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg endif windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows From a1f00cc55711e5b4b63011d5d059107b9b0b883f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 18 Nov 2013 15:30:47 +0000 Subject: [PATCH 47/55] * util/grub-mkrescue.c (main): Fix typo. --- ChangeLog | 4 ++++ util/grub-mkrescue.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1a7d8f0b..c356df282 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-18 Colin Watson + + * util/grub-mkrescue.c (main): Fix typo. + 2013-11-18 Vladimir Serbinenko * Makefile.am (default_payload.elf): Add pata to loaded modules. diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index 5eec03747..6b7239846 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -388,8 +388,7 @@ main (int argc, char *argv[]) xorriso_push ("-graft-points"); iso9660_dir = grub_util_make_temporary_dir (); - grub_util_info ("temporaray iso9660 dir is `%s'", - iso9660_dir); + grub_util_info ("temporary iso9660 dir is `%s'", iso9660_dir); boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub"); grub_install_mkdir_p (boot_grub); romdir = grub_util_path_concat (2, boot_grub, "roms"); From efb8de492ad278630d98082907a4bff1ded7cc95 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 16:32:22 +0100 Subject: [PATCH 48/55] * tests/util/grub-shell.in: Increase console size to 1024x1024. --- ChangeLog | 4 ++++ tests/util/grub-shell.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e1a7d8f0b..2303e5fa0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-18 Vladimir Serbinenko + + * tests/util/grub-shell.in: Increase console size to 1024x1024. + 2013-11-18 Vladimir Serbinenko * Makefile.am (default_payload.elf): Add pata to loaded modules. diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index b3632a883..5f20b64e0 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -307,7 +307,7 @@ else fi cat <>${cfgfile} -terminfo -g 255x255 ${term} dumb +terminfo -g 1024x1024 ${term} dumb terminal_input ${term} terminal_output ${term} EOF From 74e632fea8b57650ee15bbc7db7d29d4c4357e8d Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 16:39:45 +0100 Subject: [PATCH 49/55] * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Update clock frequency to 200 MHz, --- ChangeLog | 5 +++++ grub-core/kern/mips/qemu_mips/init.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2303e5fa0..87c4cace5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Update + clock frequency to 200 MHz, + 2013-11-18 Vladimir Serbinenko * tests/util/grub-shell.in: Increase console size to 1024x1024. diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index 2ea2eb4fd..be88b77d2 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -49,7 +49,7 @@ grub_machine_init (void) } /* FIXME: measure this. */ - grub_arch_cpuclock = 64000000; + grub_arch_cpuclock = 200000000; modend = grub_modules_get_end (); grub_mm_init_region ((void *) modend, grub_arch_memsize From 39ff43c579870df6758757663432c4849c80d532 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 16:58:55 +0100 Subject: [PATCH 50/55] * grub-core/kern/mm.c (grub_real_malloc): Don't update the pointer to current memory when allocating large chunks. This significantly decreases memory fragmentation. --- ChangeLog | 6 ++++++ grub-core/kern/mm.c | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aa39cb968..ba6af6af6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/kern/mm.c (grub_real_malloc): Don't update the pointer to + current memory when allocating large chunks. This significantly + decreases memory fragmentation. + 2013-11-18 Colin Watson * util/grub-mkrescue.c (main): Fix typo. diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c index 6111eef7e..53f3475f5 100644 --- a/grub-core/kern/mm.c +++ b/grub-core/kern/mm.c @@ -298,7 +298,10 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) /* Mark find as a start marker for next allocation to fasten it. This will have side effect of fragmenting memory as small pieces before this will be un-used. */ - *first = q; + /* So do it only for chunks under 64K. */ + if (n < (0x10000 >> GRUB_MM_ALIGN_LOG2) + || *first == p) + *first = q; return p + 1; } From 60870be86cd4b54bfdd6bcd08b82b9a99f19b812 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 18 Nov 2013 16:16:33 +0000 Subject: [PATCH 51/55] * tests/gzcompress_test.in: Skip if gzip is not installed (unlikely, but for symmetry). * tests/lzocompress_test.in: Skip if lzop is not installed. * tests/xzcompress_test.in: Skip if xz is not installed. --- ChangeLog | 7 +++++++ tests/gzcompress_test.in | 5 +++++ tests/lzocompress_test.in | 5 +++++ tests/xzcompress_test.in | 5 +++++ 4 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index aa39cb968..7f7941601 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-11-18 Colin Watson + + * tests/gzcompress_test.in: Skip if gzip is not installed (unlikely, + but for symmetry). + * tests/lzocompress_test.in: Skip if lzop is not installed. + * tests/xzcompress_test.in: Skip if xz is not installed. + 2013-11-18 Colin Watson * util/grub-mkrescue.c (main): Fix typo. diff --git a/tests/gzcompress_test.in b/tests/gzcompress_test.in index 5cc352eef..11b6bb208 100644 --- a/tests/gzcompress_test.in +++ b/tests/gzcompress_test.in @@ -19,6 +19,11 @@ grubshell=@builddir@/grub-shell . "@builddir@/grub-core/modinfo.sh" +if ! which gzip >/dev/null 2>&1; then + echo "gzip not installed; cannot test gzip compression." + exit 77 +fi + if [ "$(echo hello | "${grubshell}" --mkrescue-arg=--compress=gz)" != "Hello World" ]; then exit 1 fi diff --git a/tests/lzocompress_test.in b/tests/lzocompress_test.in index 54428c33b..41984c254 100644 --- a/tests/lzocompress_test.in +++ b/tests/lzocompress_test.in @@ -19,6 +19,11 @@ grubshell=@builddir@/grub-shell . "@builddir@/grub-core/modinfo.sh" +if ! which lzop >/dev/null 2>&1; then + echo "lzop not installed; cannot test lzo compression." + exit 77 +fi + if [ "$(echo hello | "${grubshell}" --mkrescue-arg=--compress=lzo)" != "Hello World" ]; then exit 1 fi diff --git a/tests/xzcompress_test.in b/tests/xzcompress_test.in index 63f5fd190..b2bd999ec 100644 --- a/tests/xzcompress_test.in +++ b/tests/xzcompress_test.in @@ -19,6 +19,11 @@ grubshell=@builddir@/grub-shell . "@builddir@/grub-core/modinfo.sh" +if ! which xz >/dev/null 2>&1; then + echo "xz not installed; cannot test xz compression." + exit 77 +fi + if [ "$(echo hello | "${grubshell}" --mkrescue-arg=--compress=xz)" != "Hello World" ]; then exit 1 fi From 45bf8b3a75492085f2a7a0563b301caabfbeb63d Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 17:41:37 +0100 Subject: [PATCH 52/55] * grub-core/kern/mm.c (grub_real_malloc): Decrease cut-off of moving the pointer to 32K. This is the size of cache element which is the most common allocation >1K. This way the pointer is always around blocks of 32K and so we keep performance while decreasing fragmentation. --- ChangeLog | 7 +++++++ grub-core/kern/mm.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ba6af6af6..6b66c8e51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-11-18 Vladimir Serbinenko + + * grub-core/kern/mm.c (grub_real_malloc): Decrease cut-off of moving the + pointer to 32K. This is the size of cache element which is the most + common allocation >1K. This way the pointer is always around blocks + of 32K and so we keep performance while decreasing fragmentation. + 2013-11-18 Vladimir Serbinenko * grub-core/kern/mm.c (grub_real_malloc): Don't update the pointer to diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c index 53f3475f5..1c3d02388 100644 --- a/grub-core/kern/mm.c +++ b/grub-core/kern/mm.c @@ -299,7 +299,7 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) This will have side effect of fragmenting memory as small pieces before this will be un-used. */ /* So do it only for chunks under 64K. */ - if (n < (0x10000 >> GRUB_MM_ALIGN_LOG2) + if (n < (0x8000 >> GRUB_MM_ALIGN_LOG2) || *first == p) *first = q; From bb2b275b7d5a1214ead1bea718d93ad9934b59d8 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 18 Nov 2013 17:42:54 +0100 Subject: [PATCH 53/55] * tests/grub_func_test.in: Decrease RAM size to 512M. With less fragmentation 512M is enough. --- ChangeLog | 5 +++++ tests/grub_func_test.in | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6b66c8e51..8978c7f46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-18 Vladimir Serbinenko + + * tests/grub_func_test.in: Decrease RAM size to 512M. With less + fragmentation 512M is enough. + 2013-11-18 Vladimir Serbinenko * grub-core/kern/mm.c (grub_real_malloc): Decrease cut-off of moving the diff --git a/tests/grub_func_test.in b/tests/grub_func_test.in index cfb200cf9..c8cc26376 100644 --- a/tests/grub_func_test.in +++ b/tests/grub_func_test.in @@ -3,8 +3,16 @@ set -e . "@builddir@/grub-core/modinfo.sh" +case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + # PLATFORM: Max RAM is 256M + mips-qemu_mips | mipsel-qemu_mips) + mem=256M;; + *) + mem=512M;; +esac + # Increase memory as some of tests are high-resolution and need a lot of memory. -out=`echo all_functional_test | @builddir@/grub-shell --timeout=3600 --files="/boot/grub/fonts/unicode.pf2"="@builddir@/"unicode.pf2 --qemu-opts="-m 1G"` +out=`echo all_functional_test | @builddir@/grub-shell --timeout=3600 --files="/boot/grub/fonts/unicode.pf2"="@builddir@/"unicode.pf2 --qemu-opts="-m $mem"` if [ "$(echo "$out" | tail -n 1)" != "ALL TESTS PASSED" ]; then echo "Functional test failure: $out" From d53f4900d7a5df63614c15315d413cb1d2e7a34a Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 18 Nov 2013 18:00:52 +0100 Subject: [PATCH 54/55] * grub-core/mmap/efi/mmap.c (grub_mmap_register): Round up/down to 4k page boundaries as expected by firmware rather than 1k boundaries. (grub_mmap_malign_and_register): Likewise. --- ChangeLog | 7 +++++++ grub-core/mmap/efi/mmap.c | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index aee611641..ca8ea2e5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-11-18 Josh Triplett + + * grub-core/mmap/efi/mmap.c (grub_mmap_register): Round up/down to + 4k page boundaries as expected by firmware rather than 1k + boundaries. + (grub_mmap_malign_and_register): Likewise. + 2013-11-18 Vladimir Serbinenko * tests/grub_func_test.in: Decrease RAM size to 512M. With less diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index 4f17c8b53..a77efe81d 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -184,8 +184,8 @@ grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type) return 0; b = grub_efi_system_table->boot_services; - address = start & (~0x3ffULL); - pages = (end - address + 0x3ff) >> 12; + address = start & (~0xfffULL); + pages = (end - address + 0xfff) >> 12; status = efi_call_2 (b->free_pages, address, pages); if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND) { @@ -263,7 +263,7 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), atype = GRUB_EFI_ALLOCATE_ANY_PAGES; #endif - pages = (size + 0x3ff) >> 12; + pages = (size + 0xfff) >> 12; status = efi_call_4 (b->allocate_pages, atype, make_efi_memtype (type), pages, &address); if (status != GRUB_EFI_SUCCESS) From 7960d3e1823bd3ea569109dcfe269447c3589fac Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 19 Nov 2013 14:31:40 +0100 Subject: [PATCH 55/55] * grub-core/kern/x86_64/efi/startup.S (_start): Align the stack to a 16-byte boundary, as required by the x86-64 ABI, before calling grub_main. In some cases, GCC emits code that assumes this alignment, which crashes if not aligned. The EFI firmware is also entitled to assume that stack alignment without checking. --- ChangeLog | 8 ++++++++ grub-core/kern/x86_64/efi/startup.S | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca8ea2e5d..38a97db5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-11-19 Josh Triplett + + * grub-core/kern/x86_64/efi/startup.S (_start): Align the stack to a + 16-byte boundary, as required by the x86-64 ABI, before calling + grub_main. In some cases, GCC emits code that assumes this + alignment, which crashes if not aligned. The EFI firmware is also + entitled to assume that stack alignment without checking. + 2013-11-18 Josh Triplett * grub-core/mmap/efi/mmap.c (grub_mmap_register): Round up/down to diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S index f86f01969..9357e5c5d 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/grub-core/kern/x86_64/efi/startup.S @@ -30,6 +30,6 @@ _start: movq %rcx, EXT_C(grub_efi_image_handle)(%rip) movq %rdx, EXT_C(grub_efi_system_table)(%rip) + andq $~0xf, %rsp call EXT_C(grub_main) - ret - + /* Doesn't return. */