source: mainline/uspace/lib/label/src/mbr.c@ 3faa03d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3faa03d was 3faa03d, checked in by Jiri Svoboda <jiri@…>, 10 years ago

Liblabel reading GPT and MBR partitions (primary only).

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup liblabel
30 * @{
31 */
32/**
33 * @file Master Boot Record label
34 */
35
36#include <block.h>
37#include <byteorder.h>
38#include <errno.h>
39#include <stdlib.h>
40
41#include "std/mbr.h"
42#include "mbr.h"
43
44static int mbr_open(service_id_t, label_t **);
45static int mbr_create(service_id_t, label_t **);
46static void mbr_close(label_t *);
47static int mbr_destroy(label_t *);
48static label_part_t *mbr_part_first(label_t *);
49static label_part_t *mbr_part_next(label_part_t *);
50static void mbr_part_get_info(label_part_t *, label_part_info_t *);
51static int mbr_part_create(label_t *, label_part_spec_t *, label_part_t **);
52static int mbr_part_destroy(label_part_t *);
53
54static int mbr_pte_to_part(label_t *, mbr_pte_t *);
55
56label_ops_t mbr_label_ops = {
57 .open = mbr_open,
58 .create = mbr_create,
59 .close = mbr_close,
60 .destroy = mbr_destroy,
61 .part_first = mbr_part_first,
62 .part_next = mbr_part_next,
63 .part_get_info = mbr_part_get_info,
64 .part_create = mbr_part_create,
65 .part_destroy = mbr_part_destroy
66};
67
68static int mbr_open(service_id_t sid, label_t **rlabel)
69{
70 label_t *label = NULL;
71 mbr_br_block_t *mbr = NULL;
72 mbr_pte_t *eptr;
73 uint16_t sgn;
74 size_t bsize;
75 uint32_t entry;
76 int rc;
77
78 rc = block_get_bsize(sid, &bsize);
79 if (rc != EOK) {
80 rc = EIO;
81 goto error;
82 }
83
84 if (bsize < 512 || (bsize % 512) != 0) {
85 rc = EINVAL;
86 goto error;
87 }
88
89 mbr = calloc(1, bsize);
90 if (mbr == NULL) {
91 rc = ENOMEM;
92 goto error;
93 }
94
95 rc = block_read_direct(sid, MBR_BA, 1, mbr);
96 if (rc != EOK) {
97 rc = EIO;
98 goto error;
99 }
100
101 label = calloc(1, sizeof(label_t));
102 if (label == NULL)
103 return ENOMEM;
104
105 list_initialize(&label->parts);
106
107 /* Verify boot record signature */
108 sgn = uint16_t_le2host(mbr->signature);
109 if (sgn != mbr_br_signature) {
110 rc = EIO;
111 goto error;
112 }
113
114 for (entry = 0; entry < mbr_nprimary; entry++) {
115 eptr = &mbr->pte[entry];
116 rc = mbr_pte_to_part(label, eptr);
117 if (rc != EOK)
118 goto error;
119 }
120
121 free(mbr);
122 mbr = NULL;
123
124 label->ops = &mbr_label_ops;
125 label->ltype = lt_mbr;
126 *rlabel = label;
127 return EOK;
128error:
129 free(mbr);
130 free(label);
131 return rc;
132}
133
134static int mbr_create(service_id_t sid, label_t **rlabel)
135{
136 return EOK;
137}
138
139static void mbr_close(label_t *label)
140{
141 free(label);
142}
143
144static int mbr_destroy(label_t *label)
145{
146 return EOK;
147}
148
149static label_part_t *mbr_part_first(label_t *label)
150{
151 link_t *link;
152
153 link = list_first(&label->parts);
154 if (link == NULL)
155 return NULL;
156
157 return list_get_instance(link, label_part_t, llabel);
158}
159
160static label_part_t *mbr_part_next(label_part_t *part)
161{
162 link_t *link;
163
164 link = list_next(&part->llabel, &part->label->parts);
165 if (link == NULL)
166 return NULL;
167
168 return list_get_instance(link, label_part_t, llabel);
169}
170
171static void mbr_part_get_info(label_part_t *part, label_part_info_t *pinfo)
172{
173 pinfo->block0 = part->block0;
174 pinfo->nblocks = part->nblocks;
175}
176
177static int mbr_part_create(label_t *label, label_part_spec_t *pspec,
178 label_part_t **rpart)
179{
180 return EOK;
181}
182
183static int mbr_part_destroy(label_part_t *part)
184{
185 return EOK;
186}
187
188static int mbr_pte_to_part(label_t *label, mbr_pte_t *pte)
189{
190 label_part_t *part;
191 uint32_t block0;
192 uint32_t nblocks;
193
194 block0 = uint32_t_le2host(pte->first_lba);
195 nblocks = uint32_t_le2host(pte->length);
196
197 /* See UEFI specification 2.0 section 5.2.1 Legacy Master Boot Record */
198 if (pte->ptype == mbr_pt_unused || pte->ptype == mbr_pt_extended ||
199 nblocks == 0)
200 return EOK;
201
202 part = calloc(1, sizeof(label_part_t));
203 if (part == NULL)
204 return ENOMEM;
205
206 part->block0 = block0;
207 part->nblocks = nblocks;
208
209 /*
210 * TODO: Verify
211 * - partition must reside on disk
212 * - partition must not overlap any other partition
213 */
214
215 part->label = label;
216 list_append(&part->llabel, &label->parts);
217 return EOK;
218}
219
220/** @}
221 */
Note: See TracBrowser for help on using the repository browser.