1 /* ----------------------------------------------------------------------- * 2 * 3 * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved 4 * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin 5 * Copyright (C) 2010 Shao Miller 6 * 7 * Permission is hereby granted, free of charge, to any person 8 * obtaining a copy of this software and associated documentation 9 * files (the "Software"), to deal in the Software without 10 * restriction, including without limitation the rights to use, 11 * copy, modify, merge, publish, distribute, sublicense, and/or 12 * sell copies of the Software, and to permit persons to whom 13 * the Software is furnished to do so, subject to the following 14 * conditions: 15 * 16 * The above copyright notice and this permission notice shall 17 * be included in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 * OTHER DEALINGS IN THE SOFTWARE. 27 * 28 * ----------------------------------------------------------------------- */ 29 30 /** 31 * @file syslinux/disk.h 32 * 33 * Deal with disks and partitions 34 */ 35 36 #ifndef _SYSLINUX_DISK_H 37 #define _SYSLINUX_DISK_H 38 39 #include <com32.h> 40 #include <stdint.h> 41 42 #define SECTOR 512u /* bytes/sector */ 43 44 enum disk_op_codes { 45 EBIOS_READ_CODE = 0x42, /* Extended read */ 46 EBIOS_WRITE_CODE = 0x43, /* Extended write */ 47 CHS_READ_CODE = 0x02, 48 CHS_WRITE_CODE = 0x03, 49 }; 50 51 struct disk_info { 52 int disk; 53 int ebios; /* EBIOS supported on this disk */ 54 int cbios; /* CHS geometry is valid */ 55 uint32_t bps; /* bytes per sector */ 56 uint64_t lbacnt; /* total amount of sectors */ 57 uint32_t cyl; 58 uint32_t head; 59 uint32_t spt; 60 }; 61 62 struct disk_ebios_dapa { 63 uint16_t len; 64 uint16_t count; 65 uint16_t off; 66 uint16_t seg; 67 uint64_t lba; 68 } __attribute__ ((packed)); 69 70 struct disk_ebios_eparam { 71 uint16_t len; 72 uint16_t info; 73 uint32_t cyl; 74 uint32_t head; 75 uint32_t spt; 76 uint64_t lbacnt; 77 uint16_t bps; /* bytes per sector */ 78 uint32_t edd; 79 uint16_t dpi_sig; 80 uint8_t dpi_len; 81 char reserved1[3]; 82 char hostbus[4]; 83 char if_type[8]; 84 char if_path[8]; 85 char dev_path[8]; 86 char reserved2; 87 uint8_t checksum; 88 } __attribute__ ((packed)); 89 90 /** 91 * CHS (cylinder, head, sector) value extraction macros. 92 * Taken from WinVBlock. None expand to an lvalue. 93 */ 94 #define chs_head(chs) chs[0] 95 #define chs_sector(chs) (chs[1] & 0x3F) 96 #define chs_cyl_high(chs) (((uint16_t)(chs[1] & 0xC0)) << 2) 97 #define chs_cyl_low(chs) ((uint16_t)chs[2]) 98 #define chs_cylinder(chs) (chs_cyl_high(chs) | chs_cyl_low(chs)) 99 typedef uint8_t disk_chs[3]; 100 101 /* A DOS partition table entry */ 102 struct disk_dos_part_entry { 103 uint8_t active_flag; /* 0x80 if "active" */ 104 disk_chs start; 105 uint8_t ostype; 106 disk_chs end; 107 uint32_t start_lba; 108 uint32_t length; 109 } __attribute__ ((packed)); 110 111 /* A DOS MBR */ 112 struct disk_dos_mbr { 113 char code[440]; 114 uint32_t disk_sig; 115 char pad[2]; 116 struct disk_dos_part_entry table[4]; 117 uint16_t sig; 118 } __attribute__ ((packed)); 119 #define disk_mbr_sig_magic 0xAA55 120 121 /** 122 * A GPT disk/partition GUID 123 * 124 * Be careful with endianness, you must adjust it yourself 125 * iff you are directly using the fourth data chunk. 126 * There might be a better header for this... 127 */ 128 struct guid { 129 uint32_t data1; 130 uint16_t data2; 131 uint16_t data3; 132 uint64_t data4; 133 } __attribute__ ((packed)); 134 135 /* A GPT partition */ 136 struct disk_gpt_part_entry { 137 struct guid type; 138 struct guid uid; 139 uint64_t lba_first; 140 uint64_t lba_last; 141 uint64_t attribs; 142 char name[72]; 143 } __attribute__ ((packed)); 144 145 /* A GPT header */ 146 struct disk_gpt_header { 147 char sig[8]; 148 union { 149 struct { 150 uint16_t minor; 151 uint16_t major; 152 } fields __attribute__ ((packed)); 153 uint32_t uint32; 154 char raw[4]; 155 } rev __attribute__ ((packed)); 156 uint32_t hdr_size; 157 uint32_t chksum; 158 char reserved1[4]; 159 uint64_t lba_cur; 160 uint64_t lba_alt; 161 uint64_t lba_first_usable; 162 uint64_t lba_last_usable; 163 struct guid disk_guid; 164 uint64_t lba_table; 165 uint32_t part_count; 166 uint32_t part_size; 167 uint32_t table_chksum; 168 char reserved2[1]; 169 } __attribute__ ((packed)); 170 static const char disk_gpt_sig_magic[] = "EFI PART"; 171 172 extern int disk_int13_retry(const com32sys_t * inreg, com32sys_t * outreg); 173 extern int disk_get_params(int disk, struct disk_info *const diskinfo); 174 extern void *disk_read_sectors(const struct disk_info *const diskinfo, 175 uint64_t lba, uint8_t count); 176 extern int disk_write_sectors(const struct disk_info *const diskinfo, 177 uint64_t lba, const void *data, uint8_t count); 178 extern int disk_write_verify_sectors(const struct disk_info *const diskinfo, 179 uint64_t lba, const void *buf, uint8_t count); 180 extern void disk_dos_part_dump(const struct disk_dos_part_entry *const part); 181 extern void guid_to_str(char *buf, const struct guid *const id); 182 extern int str_to_guid(const char *buf, struct guid *const id); 183 extern void disk_gpt_part_dump(const struct disk_gpt_part_entry *const 184 gpt_part); 185 extern void disk_gpt_header_dump(const struct disk_gpt_header *const gpt); 186 187 #endif /* _SYSLINUX_DISK_H */ 188