cgpt_boot.c revision a05814398202c4147a5e3f28474830ec0a9a0a90
1// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "cgpt.h" 6 7#include <errno.h> 8#include <fcntl.h> 9#include <string.h> 10 11#include "cgptlib_internal.h" 12#include "endian.h" 13#include "cgpt_params.h" 14 15int cgpt_boot(CgptBootParams *params) { 16 struct drive drive; 17 int retval = 1; 18 int gpt_retval= 0; 19 20 if (params == NULL) 21 return CGPT_FAILED; 22 23 if (CGPT_OK != DriveOpen(params->driveName, &drive)) 24 return CGPT_FAILED; 25 26 if (CGPT_OK != ReadPMBR(&drive)) { 27 Error("Unable to read PMBR\n"); 28 goto done; 29 } 30 31 if (params->create_pmbr) { 32 drive.pmbr.magic[0] = 0x1d; 33 drive.pmbr.magic[1] = 0x9a; 34 drive.pmbr.sig[0] = 0x55; 35 drive.pmbr.sig[1] = 0xaa; 36 memset(&drive.pmbr.part, 0, sizeof(drive.pmbr.part)); 37 drive.pmbr.part[0].f_head = 0x00; 38 drive.pmbr.part[0].f_sect = 0x02; 39 drive.pmbr.part[0].f_cyl = 0x00; 40 drive.pmbr.part[0].type = 0xee; 41 drive.pmbr.part[0].l_head = 0xff; 42 drive.pmbr.part[0].l_sect = 0xff; 43 drive.pmbr.part[0].l_cyl = 0xff; 44 drive.pmbr.part[0].f_lba = htole32(1); 45 uint32_t max = 0xffffffff; 46 if (drive.gpt.drive_sectors < 0xffffffff) 47 max = drive.gpt.drive_sectors - 1; 48 drive.pmbr.part[0].num_sect = htole32(max); 49 } 50 51 if (params->partition) { 52 if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { 53 Error("GptSanityCheck() returned %d: %s\n", 54 gpt_retval, GptError(gpt_retval)); 55 goto done; 56 } 57 58 if (params->partition > GetNumberOfEntries(&drive.gpt)) { 59 Error("invalid partition number: %d\n", params->partition); 60 goto done; 61 } 62 63 uint32_t index = params->partition - 1; 64 GptEntry *entry = GetEntry(&drive.gpt, ANY_VALID, index); 65 memcpy(&drive.pmbr.boot_guid, &entry->unique, sizeof(Guid)); 66 } 67 68 if (params->bootfile) { 69 int fd = open(params->bootfile, O_RDONLY); 70 if (fd < 0) { 71 Error("Can't read %s: %s\n", params->bootfile, strerror(errno)); 72 goto done; 73 } 74 75 int n = read(fd, drive.pmbr.bootcode, sizeof(drive.pmbr.bootcode)); 76 if (n < 1) { 77 Error("problem reading %s: %s\n", params->bootfile, strerror(errno)); 78 close(fd); 79 goto done; 80 } 81 82 close(fd); 83 } 84 85 char buf[GUID_STRLEN]; 86 GuidToStr(&drive.pmbr.boot_guid, buf, sizeof(buf)); 87 printf("%s\n", buf); 88 89 // Write it all out 90 if (CGPT_OK == WritePMBR(&drive)) 91 retval = 0; 92 93done: 94 (void) DriveClose(&drive, 1); 95 return retval; 96} 97