• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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