diff options
author | Jeremy Katz <katzj@redhat.com> | 2006-06-10 02:25:55 +0000 |
---|---|---|
committer | Jeremy Katz <katzj@redhat.com> | 2006-06-10 02:25:55 +0000 |
commit | f31e502406d443f6e3f98f8c612cf956a9be1c16 (patch) | |
tree | f0e15815d3d86eff02ae736581781d1f43cb44ec /utils | |
parent | 05fd4dd474baaeba69bad50a7d351f260dde9431 (diff) | |
download | anaconda-f31e502406d443f6e3f98f8c612cf956a9be1c16.tar.gz anaconda-f31e502406d443f6e3f98f8c612cf956a9be1c16.tar.xz anaconda-f31e502406d443f6e3f98f8c612cf956a9be1c16.zip |
not here
Diffstat (limited to 'utils')
-rw-r--r-- | utils/gptsync/Makefile | 47 | ||||
-rw-r--r-- | utils/gptsync/README | 41 | ||||
-rw-r--r-- | utils/gptsync/gptsync.c | 695 | ||||
-rw-r--r-- | utils/gptsync/gptsync.h | 122 | ||||
-rw-r--r-- | utils/gptsync/os_unix.c | 261 | ||||
-rw-r--r-- | utils/gptsync/syslinux_mbr.h | 90 |
6 files changed, 0 insertions, 1256 deletions
diff --git a/utils/gptsync/Makefile b/utils/gptsync/Makefile deleted file mode 100644 index 8302933d3..000000000 --- a/utils/gptsync/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# Makefile for gptsync on Unix platforms -# - -OBJS = gptsync.o os_unix.o - -TARGET = gptsync - -CPPFLAGS = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -CFLAGS = -Wall -Werror -LDFLAGS = -LIBS = - -# real making - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) - -$(OBJS): %.o: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) -c $< - -# cleanup - -clean: - $(RM) *.o *~ *% $(TARGET) - -distclean: clean - $(RM) .depend - -# automatic dependencies - -depend: dep -dep: - for i in $(OBJS:.o=.c) ; do $(CC) $(CPPFLAGS) -MM $$i ; done > .depend - -ifeq (.depend,$(wildcard .depend)) -include .depend -endif - -# eof - -# install target for anaconda -install: all - mkdir -p $(DESTDIR)/usr/sbin - install -m 755 gptsync $(DESTDIR)/usr/sbin/gptsync diff --git a/utils/gptsync/README b/utils/gptsync/README deleted file mode 100644 index f364b6367..000000000 --- a/utils/gptsync/README +++ /dev/null @@ -1,41 +0,0 @@ -gptsync is from refit (refit.sf.net). It has been modified to -1) Not prompt if you want to copy -2) Default to Linux native (0x83) instead of fat32 partition id - -The original license follows. - - - rEFIt License -=============== - -Copyright (c) 2006 Christoph Pfisterer -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the - distribution. - - * Neither the name of Christoph Pfisterer nor the names of the - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/utils/gptsync/gptsync.c b/utils/gptsync/gptsync.c deleted file mode 100644 index bd224cbb4..000000000 --- a/utils/gptsync/gptsync.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * gptsync/gptsync.c - * Platform-independent code for syncing GPT and MBR - * - * Copyright (c) 2006 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gptsync.h" - -#include "syslinux_mbr.h" - -// types - -typedef struct { - UINT8 flags; - UINT8 start_chs[3]; - UINT8 type; - UINT8 end_chs[3]; - UINT32 start_lba; - UINT32 size; -} MBR_PARTITION_INFO; - -typedef struct { - UINT8 type; - CHARN *name; -} MBR_PARTTYPE; - -typedef struct { - UINT64 signature; - UINT32 spec_revision; - UINT32 header_size; - UINT32 header_crc32; - UINT32 reserved; - UINT64 header_lba; - UINT64 alternate_header_lba; - UINT64 first_usable_lba; - UINT64 last_usable_lba; - UINT8 disk_guid[16]; - UINT64 entry_lba; - UINT32 entry_count; - UINT32 entry_size; - UINT32 entry_crc32; -} GPT_HEADER; - -typedef struct { - UINT8 type_guid[16]; - UINT8 partition_guid[16]; - UINT64 start_lba; - UINT64 end_lba; - UINT64 attributes; - CHAR16 name[36]; -} GPT_ENTRY; - -#define GPT_KIND_SYSTEM (0) -#define GPT_KIND_DATA (1) -#define GPT_KIND_BASIC_DATA (2) -#define GPT_KIND_FATAL (3) - -typedef struct { - UINT8 guid[16]; - UINT8 mbr_type; - CHARN *name; - UINTN kind; -} GPT_PARTTYPE; - -typedef struct { - UINTN index; - UINT64 start_lba; - UINT64 end_lba; - UINTN mbr_type; - UINT8 gpt_type[16]; - GPT_PARTTYPE *gpt_parttype; - BOOLEAN active; -} PARTITION_INFO; - -// variables - -UINT8 empty_guid[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; - -PARTITION_INFO mbr_parts[4]; -UINTN mbr_part_count = 0; -PARTITION_INFO gpt_parts[128]; -UINTN gpt_part_count = 0; - -PARTITION_INFO new_mbr_parts[4]; -UINTN new_mbr_part_count = 0; - -UINT8 sector[512]; - -MBR_PARTTYPE mbr_types[] = { - { 0x01, STR("FAT12") }, - { 0x04, STR("FAT16 <32M") }, - { 0x05, STR("DOS Extended") }, - { 0x06, STR("FAT16") }, - { 0x07, STR("NTFS") }, - { 0x0b, STR("FAT32") }, - { 0x0c, STR("FAT32 (LBA)") }, - { 0x0e, STR("FAT16 (LBA)") }, - { 0x0f, STR("Win95 Extended (LBA)") }, - { 0x11, STR("Hidden FAT12") }, - { 0x14, STR("Hidden FAT16 <32M") }, - { 0x16, STR("Hidden FAT16") }, - { 0x17, STR("Hidden NTFS") }, - { 0x1b, STR("Hidden FAT32") }, - { 0x1c, STR("Hidden FAT32 (LBA)") }, - { 0x1e, STR("Hidden FAT16 (LBA)") }, - { 0x82, STR("Linux swap / Solaris") }, - { 0x83, STR("Linux") }, - { 0x85, STR("Linux Extended") }, - { 0x86, STR("NTFS volume set") }, - { 0x87, STR("NTFS volume set") }, - { 0x8e, STR("Linux LVM") }, - { 0xa5, STR("FreeBSD") }, - { 0xa6, STR("OpenBSD") }, - { 0xa7, STR("NeXTSTEP") }, - { 0xa9, STR("NetBSD") }, - { 0xaf, STR("Mac OS X HFS+") }, - { 0xeb, STR("BeOS") }, - { 0xee, STR("EFI Protective") }, - { 0xef, STR("EFI System (FAT)") }, - { 0xfd, STR("Linux RAID") }, - { 0, NULL }, -}; - -GPT_PARTTYPE gpt_types[] = { - { "\x28\x73\x2A\xC1\x1F\xF8\xD2\x11\xBA\x4B\x00\xA0\xC9\x3E\xC9\x3B", 0xef, STR("EFI System (FAT)"), GPT_KIND_SYSTEM }, - { "\x41\xEE\x4D\x02\xE7\x33\xD3\x11\x9D\x69\x00\x08\xC7\x81\xF3\x9F", 0x00, STR("MBR partition scheme"), GPT_KIND_FATAL }, - { "\x16\xE3\xC9\xE3\x5C\x0B\xB8\x4D\x81\x7D\xF9\x2D\xF0\x02\x15\xAE", 0x00, STR("MS Reserved"), GPT_KIND_SYSTEM }, - { "\xA2\xA0\xD0\xEB\xE5\xB9\x33\x44\x87\xC0\x68\xB6\xB7\x26\x99\xC7", 0x00, STR("Basic Data"), GPT_KIND_BASIC_DATA }, - { "\xAA\xC8\x08\x58\x8F\x7E\xE0\x42\x85\xD2\xE1\xE9\x04\x34\xCF\xB3", 0x00, STR("MS LDM Metadata"), GPT_KIND_FATAL }, - { "\xA0\x60\x9B\xAF\x31\x14\x62\x4F\xBC\x68\x33\x11\x71\x4A\x69\xAD", 0x00, STR("MS LDM Data"), GPT_KIND_FATAL }, - { "\x0F\x88\x9D\xA1\xFC\x05\x3B\x4D\xA0\x06\x74\x3F\x0F\x84\x91\x1E", 0xfd, STR("Linux RAID"), GPT_KIND_DATA }, - { "\x6D\xFD\x57\x06\xAB\xA4\xC4\x43\x84\xE5\x09\x33\xC8\x4B\x4F\x4F", 0x82, STR("Linux Swap"), GPT_KIND_DATA }, - { "\x79\xD3\xD6\xE6\x07\xF5\xC2\x44\xA2\x3C\x23\x8F\x2A\x3D\xF9\x28", 0x8e, STR("Linux LVM"), GPT_KIND_DATA }, - { "\x39\x33\xA6\x8D\x07\x00\xC0\x60\xC4\x36\x08\x3A\xC8\x23\x09\x08", 0x00, STR("Linux Reserved"), GPT_KIND_SYSTEM }, - { "\x00\x53\x46\x48\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xaf, STR("Mac OS X HFS+"), GPT_KIND_DATA }, - { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, NULL, 0 }, -}; -GPT_PARTTYPE gpt_dummy_type = - { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, STR("Unknown"), GPT_KIND_FATAL }; - -// -// MBR functions -// - -static CHARN * mbr_parttype_name(UINT8 type) -{ - int i; - - for (i = 0; mbr_types[i].name; i++) - if (mbr_types[i].type == type) - return mbr_types[i].name; - return STR("Unknown"); -} - -static UINTN read_mbr(VOID) -{ - UINTN status; - UINTN i; - BOOLEAN used; - MBR_PARTITION_INFO *table; - - Print(L"\nCurrent MBR partition table:\n"); - - // read MBR data - status = read_sector(0, sector); - if (status != 0) - return status; - - // check for validity - if (*((UINT16 *)(sector + 510)) != 0xaa55) { - Print(L" No MBR partition table present!\n"); - return 1; - } - table = (MBR_PARTITION_INFO *)(sector + 446); - for (i = 0; i < 4; i++) { - if (table[i].flags != 0x00 && table[i].flags != 0x80) { - Print(L" MBR partition table is invalid!\n"); - return 1; - } - } - - // check if used - used = FALSE; - for (i = 0; i < 4; i++) { - if (table[i].start_lba > 0 && table[i].size > 0) { - used = TRUE; - break; - } - } - if (!used) { - Print(L" No partitions defined\n"); - return 0; - } - - // dump current state & fill internal structures - Print(L" # A Start LBA End LBA Type\n"); - for (i = 0; i < 4; i++) { - if (table[i].start_lba == 0 || table[i].size == 0) - continue; - - mbr_parts[mbr_part_count].index = i; - mbr_parts[mbr_part_count].start_lba = (UINT64)table[i].start_lba; - mbr_parts[mbr_part_count].end_lba = (UINT64)table[i].start_lba + (UINT64)table[i].size - 1; - mbr_parts[mbr_part_count].mbr_type = table[i].type; - mbr_parts[mbr_part_count].active = (table[i].flags == 0x80) ? TRUE : FALSE; - - Print(L" %d %s %12lld %12lld %02x %s\n", - mbr_parts[mbr_part_count].index + 1, - mbr_parts[mbr_part_count].active ? STR("*") : STR(" "), - mbr_parts[mbr_part_count].start_lba, - mbr_parts[mbr_part_count].end_lba, - mbr_parts[mbr_part_count].mbr_type, - mbr_parttype_name(mbr_parts[mbr_part_count].mbr_type)); - - mbr_part_count++; - } - - return 0; -} - -static UINTN check_mbr(VOID) -{ - UINTN i, k; - - // check each entry - for (i = 0; i < mbr_part_count; i++) { - // check for overlap - for (k = 0; k < mbr_part_count; k++) { - if (k != i && !(mbr_parts[i].start_lba > mbr_parts[k].end_lba || mbr_parts[k].start_lba > mbr_parts[i].end_lba)) { - Print(L"Status: MBR partition table is invalid, partitions overlap.\n"); - return 1; - } - } - - // check for extended partitions - if (mbr_parts[i].mbr_type == 0x05 || mbr_parts[i].mbr_type == 0x0f || mbr_parts[i].mbr_type == 0x85) { - Print(L"Status: Extended partition found in MBR table, will not touch this disk.\n", - gpt_parts[i].gpt_parttype->name); - return 1; - } - } - - return 0; -} - -static UINTN write_mbr(VOID) -{ - UINTN status; - UINTN i, k; - UINT8 active; - UINT64 lba; - MBR_PARTITION_INFO *table; - BOOLEAN have_bootcode; - - Print(L"\nWriting new MBR...\n"); - - // read MBR data - status = read_sector(0, sector); - if (status != 0) - return status; - - // write partition table - *((UINT16 *)(sector + 510)) = 0xaa55; - - table = (MBR_PARTITION_INFO *)(sector + 446); - active = 0x80; - for (i = 0; i < 4; i++) { - for (k = 0; k < new_mbr_part_count; k++) { - if (new_mbr_parts[k].index == i) - break; - } - if (k >= new_mbr_part_count) { - // unused entry - table[i].flags = 0; - table[i].start_chs[0] = 0; - table[i].start_chs[1] = 0; - table[i].start_chs[2] = 0; - table[i].type = 0; - table[i].end_chs[0] = 0; - table[i].end_chs[1] = 0; - table[i].end_chs[2] = 0; - table[i].start_lba = 0; - table[i].size = 0; - } else { - if (new_mbr_parts[k].active) { - table[i].flags = active; - active = 0x00; - } else - table[i].flags = 0x00; - table[i].start_chs[0] = 0xfe; - table[i].start_chs[1] = 0xff; - table[i].start_chs[2] = 0xff; - table[i].type = new_mbr_parts[k].mbr_type; - table[i].end_chs[0] = 0xfe; - table[i].end_chs[1] = 0xff; - table[i].end_chs[2] = 0xff; - - lba = new_mbr_parts[k].start_lba; - if (lba > 0xffffffffULL) { - Print(L"Warning: Partition %d starts beyond 2 TiB limit\n", i+1); - lba = 0xffffffffULL; - } - table[i].start_lba = (UINT32)lba; - - lba = new_mbr_parts[k].end_lba + 1 - new_mbr_parts[k].start_lba; - if (lba > 0xffffffffULL) { - Print(L"Warning: Partition %d extends beyond 2 TiB limit\n", i+1); - lba = 0xffffffffULL; - } - table[i].size = (UINT32)lba; - } - } - - // add boot code if necessary - have_bootcode = FALSE; - for (i = 0; i < MBR_BOOTCODE_SIZE; i++) { - if (sector[i] != 0) { - have_bootcode = TRUE; - break; - } - } - if (!have_bootcode) { - // no boot code found in the MBR, add the syslinux MBR code - SetMem(sector, MBR_BOOTCODE_SIZE, 0); - CopyMem(sector, syslinux_mbr, SYSLINUX_MBR_SIZE); - } - - // write MBR data - status = write_sector(0, sector); - if (status != 0) - return status; - - Print(L"MBR updated successfully!\n"); - - return 0; -} - -// -// GPT functions -// - -static GPT_PARTTYPE * gpt_parttype(UINT8 *type_guid) -{ - int i; - - for (i = 0; gpt_types[i].name; i++) - if (guids_are_equal(gpt_types[i].guid, type_guid)) - return &(gpt_types[i]); - return &gpt_dummy_type; -} - -static UINTN read_gpt(VOID) -{ - UINTN status; - GPT_HEADER *header; - GPT_ENTRY *entry; - UINT64 entry_lba; - UINTN entry_count, entry_size, i; - - Print(L"\nCurrent GPT partition table:\n"); - - // read GPT header - status = read_sector(1, sector); - if (status != 0) - return status; - - // check signature - header = (GPT_HEADER *)sector; - if (header->signature != 0x5452415020494645ULL) { - Print(L" No GPT partition table present!\n"); - return 0; - } - if (header->spec_revision != 0x00010000UL) { - Print(L" Warning: Unknown GPT spec revision 0x%08x\n", header->spec_revision); - } - if ((512 % header->entry_size) > 0 || header->entry_size > 512) { - Print(L" Error: Invalid GPT entry size (misaligned or more than 512 bytes)\n"); - return 0; - } - - // read entries - entry_lba = header->entry_lba; - entry_size = header->entry_size; - entry_count = header->entry_count; - - Print(L" # Start LBA End LBA Type\n"); - for (i = 0; i < entry_count; i++) { - if (((i * entry_size) % 512) == 0) { - status = read_sector(entry_lba, sector); - if (status != 0) - return status; - entry_lba++; - } - entry = (GPT_ENTRY *)(sector + ((i * entry_size) % 512)); - - if (guids_are_equal(entry->type_guid, empty_guid)) - continue; - - gpt_parts[gpt_part_count].index = i; - gpt_parts[gpt_part_count].start_lba = entry->start_lba; - gpt_parts[gpt_part_count].end_lba = entry->end_lba; - gpt_parts[gpt_part_count].mbr_type = 0; - copy_guid(gpt_parts[gpt_part_count].gpt_type, entry->type_guid); - gpt_parts[gpt_part_count].gpt_parttype = gpt_parttype(gpt_parts[gpt_part_count].gpt_type); - gpt_parts[gpt_part_count].active = FALSE; - - Print(L" %d %12lld %12lld %s\n", - gpt_parts[gpt_part_count].index + 1, - gpt_parts[gpt_part_count].start_lba, - gpt_parts[gpt_part_count].end_lba, - gpt_parts[gpt_part_count].gpt_parttype->name); - - gpt_part_count++; - } - - return 0; -} - -static UINTN check_gpt(VOID) -{ - UINTN i, k; - BOOLEAN found_data_parts; - - if (gpt_part_count == 0) { - Print(L"Status: No GPT partition table, no need to sync.\n"); - return 1; - } - - // check each entry - found_data_parts = FALSE; - for (i = 0; i < gpt_part_count; i++) { - // check sanity - if (gpt_parts[i].end_lba < gpt_parts[i].start_lba) { - Print(L"Status: GPT partition table is invalid.\n"); - return 1; - } - // check for overlap - for (k = 0; k < gpt_part_count; k++) { - if (k != i && !(gpt_parts[i].start_lba > gpt_parts[k].end_lba || gpt_parts[k].start_lba > gpt_parts[i].end_lba)) { - Print(L"Status: GPT partition table is invalid, partitions overlap.\n"); - return 1; - } - } - - // check for partitions kind - if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_FATAL) { - Print(L"Status: GPT partition of type '%s' found, will not touch this disk.\n", - gpt_parts[i].gpt_parttype->name); - return 1; - } - if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_DATA || - gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA) - found_data_parts = TRUE; - } - - if (!found_data_parts) { - Print(L"Status: GPT partition table has no data partitions, no need to sync.\n"); - return 1; - } - - return 0; -} - -// -// compare GPT and MBR tables -// - -#define ACTION_NONE (0) -#define ACTION_NOP (1) -#define ACTION_REWRITE (2) - -static UINTN analyze(VOID) -{ - UINTN action = ACTION_NONE; - UINTN i, k, iter; - UINT64 min_start_lba; - BOOLEAN have_active; - - new_mbr_part_count = 0; - - // check for common scenarios - if (mbr_part_count == 0) { - // current MBR is empty - action = ACTION_REWRITE; - } else if (mbr_part_count == 1 && mbr_parts[0].mbr_type == 0xee) { - // MBR has just the EFI Protective partition (i.e. untouched) - action = ACTION_REWRITE; - } - if (action == ACTION_NONE && mbr_part_count > 0) { - if (mbr_parts[0].mbr_type == 0xee && - gpt_parts[0].gpt_parttype->mbr_type == 0xef && - mbr_parts[0].start_lba == 1 && - mbr_parts[0].end_lba == gpt_parts[0].end_lba) { - // The Apple Way, "EFI Protective" covering the tables and the ESP - action = ACTION_NOP; - if ((mbr_part_count != gpt_part_count && gpt_part_count <= 4) || - (mbr_part_count != 4 && gpt_part_count > 4)) { - // number of partitions has changed - action = ACTION_REWRITE; - } else { - // check partition ranges and types - for (i = 1; i < mbr_part_count; i++) { - if (mbr_parts[i].start_lba != gpt_parts[i].start_lba || - mbr_parts[i].end_lba != gpt_parts[i].end_lba || - (gpt_parts[i].gpt_parttype->mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].gpt_parttype->mbr_type)) - // position or type has changed - action = ACTION_REWRITE; - } - } - } - } - if (action == ACTION_NONE && mbr_part_count > 0 && mbr_parts[0].mbr_type == 0xef) { - // The XOM Way, all partitions mirrored 1:1 - action = ACTION_REWRITE; - // check partition ranges and types - for (i = 0; i < mbr_part_count; i++) { - if (mbr_parts[i].start_lba != gpt_parts[i].start_lba || - mbr_parts[i].end_lba != gpt_parts[i].end_lba || - (gpt_parts[i].gpt_parttype->mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].gpt_parttype->mbr_type)) - // position or type has changed -> better don't touch - action = ACTION_NONE; - } - } - - if (action == ACTION_NOP) { - Print(L"Status: Tables are synchronized, no need to sync.\n"); - return 0; - } else if (action == ACTION_REWRITE) { - Print(L"Status: MBR table must be updated.\n"); - } else { - Print(L"Status: Analysis inconclusive, will not touch this disk.\n"); - return 1; - } - - // generate the new table - - // first entry: EFI Protective - new_mbr_parts[0].index = 0; - new_mbr_parts[0].start_lba = 1; - new_mbr_parts[0].mbr_type = 0xee; - new_mbr_part_count = 1; - - if (gpt_parts[0].gpt_parttype->mbr_type == 0xef) { - new_mbr_parts[0].end_lba = gpt_parts[0].end_lba; - i = 1; - } else { - min_start_lba = gpt_parts[0].start_lba; - for (k = 0; k < gpt_part_count; k++) { - if (min_start_lba > gpt_parts[k].start_lba) - min_start_lba = gpt_parts[k].start_lba; - } - new_mbr_parts[0].end_lba = min_start_lba - 1; - i = 0; - } - - // add other GPT partitions until the table is full - for (; i < gpt_part_count && new_mbr_part_count < 4; i++) { - new_mbr_parts[new_mbr_part_count].index = new_mbr_part_count; - new_mbr_parts[new_mbr_part_count].start_lba = gpt_parts[i].start_lba; - new_mbr_parts[new_mbr_part_count].end_lba = gpt_parts[i].end_lba; - new_mbr_parts[new_mbr_part_count].mbr_type = gpt_parts[i].gpt_parttype->mbr_type; - new_mbr_parts[new_mbr_part_count].active = FALSE; - - // find matching partition in the old MBR table - for (k = 0; k < mbr_part_count; k++) { - if (mbr_parts[k].start_lba == gpt_parts[i].start_lba) { - if (new_mbr_parts[new_mbr_part_count].mbr_type == 0) - new_mbr_parts[new_mbr_part_count].mbr_type = mbr_parts[k].mbr_type; - new_mbr_parts[new_mbr_part_count].active = mbr_parts[k].active; - break; - } - } - - if (new_mbr_parts[new_mbr_part_count].mbr_type == 0) { - // TODO: detect the actual file system on the partition - - // fallback: use linux native - //if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA) { - new_mbr_parts[new_mbr_part_count].mbr_type = 0x83; - } - - new_mbr_part_count++; - } - - // if no partition is active, pick one - for (iter = 0; iter < 3; iter++) { - // check - have_active = FALSE; - for (i = 0; i < new_mbr_part_count; i++) - if (new_mbr_parts[i].active) - have_active = TRUE; - if (have_active) - break; - - // set active on the first matching partition - for (i = 0; i < new_mbr_part_count; i++) { - if ((iter >= 0 && (new_mbr_parts[i].mbr_type == 0x07 || - new_mbr_parts[i].mbr_type == 0x0b || - new_mbr_parts[i].mbr_type == 0x0c)) || - (iter >= 1 && (new_mbr_parts[i].mbr_type == 0x83)) || - (iter >= 2 && i > 0)) { - new_mbr_parts[i].active = TRUE; - break; - } - } - } - - // dump table - Print(L"\nProposed new MBR partition table:\n"); - Print(L" # A Start LBA End LBA Type\n"); - for (i = 0; i < new_mbr_part_count; i++) { - Print(L" %d %s %12lld %12lld %02x %s\n", - new_mbr_parts[i].index + 1, - new_mbr_parts[i].active ? STR("*") : STR(" "), - new_mbr_parts[i].start_lba, - new_mbr_parts[i].end_lba, - new_mbr_parts[i].mbr_type, - mbr_parttype_name(new_mbr_parts[i].mbr_type)); - } - - return 0; -} - -// -// sync algorithm entry point -// - -UINTN gptsync(VOID) -{ - UINTN status = 0; - UINTN status_gpt, status_mbr; - // BOOLEAN proceed = FALSE; - - // get full information from disk - status_gpt = read_gpt(); - status_mbr = read_mbr(); - if (status_gpt != 0 || status_mbr != 0) - return (status_gpt || status_mbr); - - // cross-check current situation - Print(L"\n"); - status = check_gpt(); // check GPT for consistency - if (status != 0) - return status; - status = check_mbr(); // check MBR for consistency - if (status != 0) - return status; - status = analyze(); // analyze the situation - if (status != 0) - return status; - if (new_mbr_part_count == 0) - return status; - - // offer user the choice what to do - // status = input_boolean(STR("\nMay I update the MBR as printed above? [y/N] "), &proceed); - // if (status != 0 || proceed != TRUE) - // return status; - - // adjust the MBR and write it back - status = write_mbr(); - if (status != 0) - return status; - - return status; -} diff --git a/utils/gptsync/gptsync.h b/utils/gptsync/gptsync.h deleted file mode 100644 index c14d32959..000000000 --- a/utils/gptsync/gptsync.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * gptsync/gptsync.h - * Common header for gptsync - * - * Copyright (c) 2006 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// config -// - -#ifdef EFI32 -#define CONFIG_EFI -#endif - -// -// types -// - -#ifdef CONFIG_EFI - -#include <efi.h> -#include <efilib.h> - -#define copy_guid(destguid, srcguid) (CopyMem(destguid, srcguid, 16)) -#define guids_are_equal(guid1, guid2) (CompareMem(guid1, guid2, 16) == 0) - -typedef CHAR16 CHARN; -#define STR(x) L##x - -#endif - - -#ifndef CONFIG_EFI - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <fcntl.h> - -typedef unsigned int UINTN; -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned long UINT32; -typedef unsigned long long UINT64; -typedef void VOID; - -typedef int BOOLEAN; -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (1) -#endif - -typedef unsigned short CHAR16; -typedef char CHARN; -#define STR(x) x - -void Print(wchar_t *format, ...); - -// FUTURE: use STR(), #define Print printf - -#define CopyMem memcpy -#define SetMem memset -#define CompareMem memcmp - -#define copy_guid(destguid, srcguid) (memcpy(destguid, srcguid, 16)) -#define guids_are_equal(guid1, guid2) (memcmp(guid1, guid2, 16) == 0) - -#endif - -// -// functions provided by the OS-specific module -// - -UINTN read_sector(UINT64 lba, UINT8 *buffer); -UINTN write_sector(UINT64 lba, UINT8 *buffer); -UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out); - -// -// common platform-independent function -// - -UINTN gptsync(VOID); - -/* EOF */ diff --git a/utils/gptsync/os_unix.c b/utils/gptsync/os_unix.c deleted file mode 100644 index 775554d7d..000000000 --- a/utils/gptsync/os_unix.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * gptsync/os_unix.c - * Unix OS glue for gptsync - * - * Copyright (c) 2006 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gptsync.h" - -#include <stdarg.h> - -// variables - -static int fd; - -// -// error functions -// - -void error(const char *msg, ...) -{ - va_list par; - char buf[4096]; - - va_start(par, msg); - vsnprintf(buf, 4096, msg, par); - va_end(par); - - fprintf(stderr, "gptsync: %s\n", buf); -} - -void errore(const char *msg, ...) -{ - va_list par; - char buf[4096]; - - va_start(par, msg); - vsnprintf(buf, 4096, msg, par); - va_end(par); - - fprintf(stderr, "gptsync: %s: %s\n", buf, strerror(errno)); -} - -// -// sector I/O functions -// - -UINTN read_sector(UINT64 lba, UINT8 *buffer) -{ - off_t offset; - off_t result_seek; - ssize_t result_read; - - offset = lba * 512; - result_seek = lseek(fd, offset, SEEK_SET); - if (result_seek != offset) { - errore("Seek to %llu failed", offset); - return 1; - } - - result_read = read(fd, buffer, 512); - if (result_read < 0) { - errore("Data read failed at position %llu", offset); - return 1; - } - if (result_read != 512) { - errore("Data read fell short at position %llu", offset); - return 1; - } - return 0; -} - -UINTN write_sector(UINT64 lba, UINT8 *buffer) -{ - off_t offset; - off_t result_seek; - ssize_t result_write; - - offset = lba * 512; - result_seek = lseek(fd, offset, SEEK_SET); - if (result_seek != offset) { - errore("Seek to %llu failed", offset); - return 1; - } - - result_write = write(fd, buffer, 512); - if (result_write < 0) { - errore("Data write failed at position %llu", offset); - return 1; - } - if (result_write != 512) { - errore("Data write fell short at position %llu", offset); - return 1; - } - return 0; -} - -// -// keyboard input -// - -UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out) -{ - int c; - - printf("%s", prompt); - fflush(NULL); - - c = getchar(); - if (c == EOF) - return 1; - - if (c == 'y' || c == 'Y') { - printf("Yes\n"); - *bool_out = TRUE; - } else { - printf("No\n"); - *bool_out = FALSE; - } - - return 0; -} - -// -// EFI-style print function -// - -void Print(wchar_t *format, ...) -{ - va_list par; - char formatbuf[256]; - char buf[4096]; - int i; - - for (i = 0; format[i]; i++) - formatbuf[i] = (format[i] > 255) ? '?' : (char)(format[i] & 0xff); - formatbuf[i] = 0; - - va_start(par, format); - vsnprintf(buf, 4096, formatbuf, par); - va_end(par); - - printf("%s", buf); -} - -// -// main entry point -// - -int main(int argc, char *argv[]) -{ - char *filename; - struct stat sb; - int filekind; - UINT64 filesize; - char *reason; - int status; - - // argument check - if (argc != 2) { - fprintf(stderr, "Usage: gptsync <device>\n"); - return 1; - } - filename = argv[1]; - - // set input to unbuffered - fflush(NULL); - setvbuf(stdin, NULL, _IONBF, 0); - - // stat check - if (stat(filename, &sb) < 0) { - errore("Can't stat %.300s", filename); - return 1; - } - - filekind = 0; - filesize = 0; - reason = NULL; - if (S_ISREG(sb.st_mode)) - filesize = sb.st_size; - else if (S_ISBLK(sb.st_mode)) - filekind = 1; - else if (S_ISCHR(sb.st_mode)) - filekind = 2; - else if (S_ISDIR(sb.st_mode)) - reason = "Is a directory"; - else if (S_ISFIFO(sb.st_mode)) - reason = "Is a FIFO"; -#ifdef S_ISSOCK - else if (S_ISSOCK(sb.st_mode)) - reason = "Is a socket"; -#endif - else - reason = "Is an unknown kind of special file"; - - if (reason != NULL) { - error("%.300s: %s", filename, reason); - return 1; - } - - // open file - fd = open(filename, O_RDWR); - if (fd < 0 && errno == EBUSY) { - fd = open(filename, O_RDONLY); - if (fd >= 0) - printf("Warning: %.300s opened read-only\n", filename); - } - if (fd < 0) { - errore("Can't open %.300s", filename); - return 1; - } - - // (try to) guard against TTY character devices - if (filekind == 2) { - if (isatty(fd)) { - error("%.300s: Is a TTY device", filename); - return 1; - } - } - - // run sync algorithm - status = gptsync(); - printf("\n"); - - // close file - if (close(fd) != 0) { - errore("Error while closing %.300s", filename); - return 1; - } - - return status; -} diff --git a/utils/gptsync/syslinux_mbr.h b/utils/gptsync/syslinux_mbr.h deleted file mode 100644 index 1c33e1159..000000000 --- a/utils/gptsync/syslinux_mbr.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * include/syslinux_mbr.h - * MBR boot code - * - * The boot code in this file was taken from syslinux-3.11. It is covered - * by the following license: - * - ; ----------------------------------------------------------------------- - ; - ; Copyright 2003-2004 H. Peter Anvin - All Rights Reserved - ; - ; Permission is hereby granted, free of charge, to any person - ; obtaining a copy of this software and associated documentation - ; files (the "Software"), to deal in the Software without - ; restriction, including without limitation the rights to use, - ; copy, modify, merge, publish, distribute, sublicense, and/or - ; sell copies of the Software, and to permit persons to whom - ; the Software is furnished to do so, subject to the following - ; conditions: - ; - ; The above copyright notice and this permission notice shall - ; be included in all copies or substantial portions of the Software. - ; - ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - ; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - ; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - ; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - ; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - ; OTHER DEALINGS IN THE SOFTWARE. - ; - ; ----------------------------------------------------------------------- - * - */ - -#ifndef __SYSLINUX_MBR_H__ -#define __SYSLINUX_MBR_H__ - - -#define MBR_BOOTCODE_SIZE (440) - - -#define SYSLINUX_MBR_SIZE (304) - -static UINT8 syslinux_mbr[SYSLINUX_MBR_SIZE] = { - 0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0x8e, - 0xd0, 0xbc, 0x00, 0x7c, 0xfb, 0xfc, 0x89, 0xe6, - 0xbf, 0x00, 0x06, 0xb9, 0x00, 0x01, 0xf3, 0xa5, - 0xea, 0x1d, 0x06, 0x00, 0x00, 0x88, 0x16, 0x00, - 0x08, 0xb4, 0x08, 0xcd, 0x13, 0x31, 0xc0, 0x88, - 0xf0, 0x40, 0xa3, 0xf0, 0x06, 0x80, 0xe1, 0x3f, - 0x88, 0x0e, 0xf2, 0x06, 0xbe, 0xbe, 0x07, 0x31, - 0xc0, 0xb9, 0x04, 0x00, 0xf6, 0x04, 0x80, 0x74, - 0x03, 0x40, 0x89, 0xf7, 0x83, 0xc6, 0x10, 0xe2, - 0xf3, 0x83, 0xf8, 0x01, 0x75, 0x73, 0x8a, 0x16, - 0x00, 0x08, 0xb8, 0x00, 0x41, 0xbb, 0xaa, 0x55, - 0x31, 0xc9, 0x30, 0xf6, 0xf9, 0xcd, 0x13, 0x72, - 0x23, 0x81, 0xfb, 0x55, 0xaa, 0x75, 0x1d, 0xf6, - 0xc1, 0x01, 0x74, 0x18, 0x57, 0xbe, 0xe0, 0x06, - 0x8b, 0x5d, 0x08, 0x89, 0x5c, 0x08, 0x8b, 0x5d, - 0x0a, 0x89, 0x5c, 0x0a, 0x8a, 0x16, 0x00, 0x08, - 0xb4, 0x42, 0xeb, 0x2a, 0x57, 0x8b, 0x45, 0x08, - 0x8b, 0x55, 0x0a, 0xf7, 0x36, 0xf2, 0x06, 0x42, - 0x89, 0xd1, 0x31, 0xd2, 0xf7, 0x36, 0xf0, 0x06, - 0x88, 0xc5, 0xd1, 0xe8, 0xd1, 0xe8, 0x24, 0xc0, - 0x08, 0xc1, 0x88, 0xd6, 0x8a, 0x16, 0x00, 0x08, - 0xbb, 0x00, 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, - 0x72, 0x16, 0x5e, 0x81, 0x3e, 0xfe, 0x7d, 0x55, - 0xaa, 0x75, 0x08, 0xfa, 0xea, 0x00, 0x7c, 0x00, - 0x00, 0x77, 0x05, 0xbe, 0xf4, 0x06, 0xeb, 0x03, - 0xbe, 0x0f, 0x07, 0xac, 0x20, 0xc0, 0x74, 0x0c, - 0xb4, 0x0e, 0x8a, 0x3e, 0x62, 0x04, 0xb3, 0x07, - 0xcd, 0x10, 0xeb, 0xef, 0xeb, 0xfe, 0x00, 0x00, - 0x10, 0x00, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x0d, 0x0a, 0x00, 0x4f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, - 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, - 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0d, 0x0a, 0x00 -}; - - -#endif /* __SYSLINUX_MBR_H__ */ - -/* EOF */ |