4
* Open Hack'Ware BIOS ISOFS partition type 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
/* ISO FS partitions handlers */
28
#define ISOFS_BLOCSIZE (2048)
30
/* Generic ISO fs descriptor */
31
typedef struct isofs_desc_t isofs_desc_t;
37
} __attribute__ ((packed));
39
typedef struct iso_primary_desc_t iso_primary_desc_t;
40
struct iso_primary_desc_t {
45
uint8_t system_id[32];
46
uint8_t volume_id[32];
49
} __attribute__ ((packed));
51
/* The only descriptor we're interrested in here
52
* is El-torito boot descriptor
54
typedef struct isofs_bootdesc_t isofs_bootdesc_t;
55
struct isofs_bootdesc_t {
63
} __attribute__ ((packed));
65
#define ISO_BOOTABLE 0x88
80
typedef struct isofs_validdesc_t isofs_validdesc_t;
81
struct isofs_validdesc_t {
88
} __attribute__ ((packed));
90
typedef struct isofs_bootcat_t isofs_bootcat_t;
91
struct isofs_bootcat_t {
100
} __attribute__ ((packed));
102
part_t *isofs_probe_partitions (bloc_device_t *bd)
104
unsigned char name[32];
108
isofs_bootdesc_t bootdesc;
109
iso_primary_desc_t primdesc;
111
isofs_validdesc_t *valid;
112
isofs_bootcat_t *bootcat;
115
uint32_t nsect, bloc, offset, length;
119
buffer = malloc(ISOFS_BLOCSIZE);
123
/* The descriptors start at offset 0x8000 */
124
for (bloc = 0x8000 / ISOFS_BLOCSIZE; end_reached == 0; bloc++) {
125
bd_seek(bd, bloc, 0);
126
if (bd_read(bd, buffer, ISOFS_BLOCSIZE) < 0) {
127
ERROR("%s bloc_read %d failed\n", __func__, bloc);
130
if (strncmp("CD001", desc->desc.ID, 5) != 0) {
131
// MSG("\rNo ISO9660 signature\n");
134
/* We found at least one valid descriptor */
135
switch (desc->desc.type) {
137
/* El-torito descriptor, great ! */
138
DPRINTF("El-torito descriptor: %08x %d\n", desc->bootdesc.catalog,
139
(char *)&desc->bootdesc.catalog - (char *)desc);
140
boot_desc = get_le32(&desc->bootdesc.catalog);
143
/* ISOFS primary descriptor */
144
DPRINTF("ISOFS primary descriptor (%d %d)\n",
145
get_le32(&desc->primdesc.volume_size) * 2048,
146
get_le32(&desc->primdesc.volume_size));
149
/* ISOFS suplementary descriptor */
150
DPRINTF("ISOFS suplementary descriptor\n");
153
/* End of descriptor list */
154
DPRINTF("End of descriptor list\n");
159
if (boot_desc != (uint32_t)(-1)) {
160
/* Find the validation descriptor */
161
bd_seek(bd, boot_desc, 0);
162
for (i = 0; i < (ISOFS_BLOCSIZE / 64); i++) {
163
DPRINTF("ISO catalog...\n");
164
bd_read(bd, buffer, 64);
167
if (valid->ID != 0x01 || get_le16(&valid->key) != 0xAA55) {
168
ERROR("ISO catalog with invalid ID/key: %x %x\n",
169
valid->ID, valid->key);
174
#if defined (__i386__)
175
if (valid->arch != ISOBOOT_IX86) {
176
ERROR("ISO catalog not for x86: %d\n", valid->arch);
179
#elif defined (__powerpc__) || defined (_ARCH_PPC)
180
if (valid->arch != ISOBOOT_PPC && valid->arch != ISOBOOT_MAC) {
181
ERROR("ISO catalog not for PPC: %d\n", valid->arch);
185
ERROR("Unknown host architecture !\n");
189
bootcat = (void *)(valid + 1);
190
if (bootcat->bootable != ISO_BOOTABLE) {
191
ERROR("Non bootable ISO catalog\n");
194
nsect = get_le16(&bootcat->nsect);
195
switch (bootcat->media) {
196
case ISOMEDIA_NOEMUL:
197
length = nsect * ISOFS_BLOCSIZE;
198
dprintf("No emulation\n");
201
length = 1200 * 1024;
202
dprintf("1.2 MB floppy\n");
205
length = 1440 * 1024;
206
dprintf("1.44 MB floppy\n");
209
length = 2880 * 1024;
210
dprintf("2.88 MB floppy\n");
213
length = nsect * ISOFS_BLOCSIZE;
214
dprintf("HD image\n");
217
ERROR("Unknown media type: %d\n", bootcat->media);
220
offset = get_le32(&bootcat->offset);
221
/* Register boot disc */
222
part = malloc(sizeof(part_t));
224
part_set_blocsize(bd, part, ISOFS_BLOCSIZE);
225
part->start = offset;
226
part->size = (length + ISOFS_BLOCSIZE - 1) / ISOFS_BLOCSIZE;
227
part->boot_start.bloc = 0;
228
part->boot_start.offset = 0;
229
part->boot_size.bloc = length / ISOFS_BLOCSIZE;
230
part->boot_size.offset = length % ISOFS_BLOCSIZE;
232
part->boot_entry = 0;
233
if (valid->name[0] == '\0') {
234
strcpy(name, "ISOFS");
236
memcpy(name, valid->name, sizeof(valid->name));
237
name[sizeof(valid->name)] = '\0';
239
printf("Partition '%s': %p st %0x size %0x %d\n",
240
name, part, offset, length, bootcat->media);
241
printf(" boot %0x %0x load %0x entry %0x\n",
242
part->boot_start.bloc, part->boot_size.bloc,
243
part->boot_load, part->boot_entry);
244
part->flags = PART_TYPE_ISO9660 | PART_FLAG_BOOT;
245
part_register(bd, part, name, i + 1);
246
fs_raw_set_bootfile(part, part->boot_start.bloc,
247
part->boot_start.offset,
248
part->boot_size.bloc,
249
part->boot_size.offset);