4 * Open Hack'Ware BIOS partitions management
6 * Copyright (c) 2004-2005 Jocelyn Mayer
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License V2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 /* Bootable partitions detection and management */
28 part_t *part_open (bloc_device_t *bd,
29 uint32_t start, uint32_t size, uint32_t spb)
33 if (bd_seek(bd, (start + size) * spb, 0) < 0)
35 part = malloc(sizeof(part_t));
46 int part_seek (part_t *part, uint32_t bloc, uint32_t pos)
48 if (bloc > part->size) {
49 ERROR("bloc: %d part size: %d %p\n", bloc, part->size, part);
55 pos = pos % part->bloc_size;
57 pos += (bloc % part->bps) * part->bloc_size;
61 return bd_seek(part->bd, bloc, pos);
64 int part_read (part_t *part, void *buffer, int len)
66 return bd_read(part->bd, buffer, len);
69 int part_write (part_t *part, const void *buffer, int len)
71 return bd_write(part->bd, buffer, len);
74 void part_close (part_t *part)
79 uint32_t part_blocsize (part_t *part)
81 return part->bloc_size;
84 uint32_t part_flags (part_t *part)
89 uint32_t part_size (part_t *part)
94 fs_t *part_fs (part_t *part)
99 void part_private_set (part_t *part, void *private)
101 part->private = private;
104 void *part_private_get (part_t *part)
106 return part->private;
109 void part_set_blocsize (bloc_device_t *bd, part_t *part, uint32_t blocsize)
113 part->bloc_size = blocsize;
114 seclen = bd_seclen(bd);
115 if (blocsize < seclen) {
117 part->bps = bd_seclen(bd) / part->bloc_size;
118 DPRINTF("%d part blocs in one sector (%d %d)\n", part->bps,
119 part->bloc_size, bd_seclen(bd));
121 part->spb = part->bloc_size / bd_seclen(bd);
123 DPRINTF("%d sectors in one part bloc (%d %d)\n", part->spb,
124 part->bloc_size, bd_seclen(bd));
128 int part_register (bloc_device_t *bd, part_t *partition,
129 const unsigned char *name, int partnum)
133 DPRINTF("Register partition '%s'\n", name);
135 partition->next = NULL;
136 partition->name = strdup(name);
137 partition->partnum = partnum;
138 for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next)
145 part_t *part_get (bloc_device_t *bd, int partnum)
147 part_t **listp, *cur;
149 listp = _bd_parts(bd);
151 for (cur = *listp; cur != NULL; cur = cur->next) {
152 if (cur->partnum == partnum)
159 part_t *part_get_raw (bloc_device_t *bd)
164 part = malloc(sizeof(part_t));
166 seclen = bd_seclen(bd);
167 part->size = bd_maxbloc(bd);
169 part->size *= seclen / 512;
171 part->size *= 512 / seclen;
173 part->boot_start.bloc = 0;
174 part->boot_start.offset = 0;
175 part->boot_size.bloc = part->size;
176 part->boot_size.offset = 0;
178 part->boot_entry = 0;
179 part_set_blocsize(bd, part, 512);
181 part->flags = PART_TYPE_RAW | PART_FLAG_BOOT;
182 part_register(bd, part, "Raw", 0);
187 bloc_device_t *part_get_bd (part_t *part)
192 part_t *part_probe (bloc_device_t *bd, int set_raw)
194 part_t *part0 = NULL, *boot_part, **cur;
196 /* Try to find a valid boot partition */
197 boot_part = Apple_probe_partitions(bd);
198 if (boot_part == NULL) {
199 boot_part = isofs_probe_partitions(bd);
200 if (boot_part == NULL && arch == ARCH_PREP)
201 boot_part = PREP_find_partition(bd);
202 if (boot_part == NULL && set_raw != 0) {
203 dprintf("Use bloc device as raw partition\n");
206 if (_bd_parts(bd) == NULL) {
207 /* Register the 0 partition: raw partition containing the whole disk */
208 part0 = part_get_raw(bd);
210 /* Probe filesystem on each found partition */
211 for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) {
212 const unsigned char *map, *type;
213 switch ((*cur)->flags & 0x0F) {
217 case PART_TYPE_APPLE:
220 case PART_TYPE_ISO9660:
227 switch ((*cur)->flags & 0xF0) {
228 case PART_FLAG_DUMMY:
231 case PART_FLAG_DRIVER:
234 case PART_FLAG_PATCH:
244 dprintf("Probe filesystem on %s %s partition '%s' %s %p\n",
245 type, map, (*cur)->name,
246 ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "", *cur);
247 if (((*cur)->flags) & PART_FLAG_FS) {
248 if (((*cur)->flags) & PART_FLAG_BOOT)
249 (*cur)->fs = fs_probe(*cur, 1);
251 (*cur)->fs = fs_probe(*cur, 0);
252 } else if (((*cur)->flags) & PART_TYPE_RAW) {
253 (*cur)->fs = fs_probe(*cur, 2);
255 (*cur)->fs = fs_probe(*cur, 2);
257 fs_get_bootfile((*cur)->fs);
258 if (((*cur)->flags) & PART_FLAG_BOOT) {
259 dprintf("Partition is bootable (%d)\n", (*cur)->partnum);
260 bd_set_boot_part(bd, *cur, (*cur)->partnum);
261 if (boot_part == NULL)
265 dprintf("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs,
266 part_fs(boot_part), part0);
271 int part_set_boot_file (part_t *part, uint32_t start, uint32_t offset,
274 part->boot_start.bloc = start;
275 part->boot_start.offset = offset;
276 part->boot_size.bloc = size;
277 part->boot_size.offset = 0;
279 part->boot_entry = 0;
280 part->flags |= PART_FLAG_BOOT;
285 unsigned int part_get_entry (part_t *part)
287 return part->boot_entry;