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
);