4 * Open Hack'Ware PREP BIOS 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 /* PREP image management */
28 typedef struct MSDOS_part_t MSDOS_part_t
;
40 } __attribute__ ((packed
));
42 part_t
*PREP_find_partition (bloc_device_t
*bd
)
47 uint32_t boot_offset
, boot_size
;
51 buffer
= malloc(0x200);
53 if (bd_read(bd
, buffer
, 0x200) < 0) {
54 ERROR("Unable to read boot sector from boot device. Aborting...\n");
57 if (buffer
[0x1FE] != 0x55 || buffer
[0x1FF] != 0xAA) {
58 ERROR("No MSDOS signature (%x %x %x %x)\n",
59 buffer
[0x000], buffer
[0x001], buffer
[0x1FE], buffer
[0x1FF]);
62 for (i
= 0; i
< 4; i
++) {
63 p
= (void *)(&buffer
[0x1BE + (0x10 * i
)]);
64 DPRINTF("partition %d: %x is %sbootable - ", i
, p
->boot_ind
,
65 (p
->boot_ind
& 0x80) ? "" : "not ");
66 DPRINTF("start %0x end %0x type %x\n",
67 get_le32(&p
->LBA_start
), get_le32(&p
->LBA_end
), p
->sys_ind
);
69 if (p
->boot_ind
!= 0x80)
73 case 0x07: /* HPFS/NTFS */
74 goto register_nonboot
;
76 goto register_nonboot
;
77 case 0x09: /* AIX bootable */
78 /* Not supported by now */
80 case 0x0A: /* OS/2 boot manager */
81 /* Not supported by now */
83 case 0x41: /* PREP boot */
84 part
= malloc(sizeof(part_t
));
85 memset(part
, 0, sizeof(part_t
));
87 part_set_blocsize(bd
, part
, 0x200);
88 /* Convert start and size into LBA */
89 if ((p
->start_head
!= 0 || p
->start_cyl
!= 0 ||
90 p
->start_sect
!= 0) && p
->LBA_start
== 0) {
91 DPRINTF("start: use CHS\n");
92 part
->start
= bd_CHS2sect(bd
, p
->start_cyl
,
96 DPRINTF("start: use LBA\n");
97 part
->start
= get_le32(&p
->LBA_start
);
99 if ((p
->end_head
!= 0 || p
->end_cyl
!= 0 ||
100 p
->end_sect
!= 0) && p
->LBA_end
== 0) {
101 DPRINTF("end: use CHS\n");
102 part
->size
= bd_CHS2sect(bd
, p
->end_cyl
,
103 p
->end_head
, p
->end_sect
);
105 DPRINTF("end: use LBA\n");
106 part
->size
= get_le32(&p
->LBA_end
);
108 /* XXX: seems that some (AIX !)
109 * code the size here instead of partition end
111 if (part
->size
> part
->start
)
112 part
->size
-= part
->start
;
113 DPRINTF("LBA: start %0x size: %0x\n", part
->start
, part
->size
);
114 /* Now, find and check boot record */
115 part_seek(part
, 0, 0);
116 if (bd_read(bd
, buffer
, part
->bloc_size
) < 0) {
117 ERROR("%s sector_read failed (%d)\n", __func__
, i
);
122 if (buffer
[0x1FE] != 0x55 || buffer
[0x1FF] != 0xAA) {
123 ERROR("No MSDOS signature on PREP boot record\n");
128 boot_offset
= get_le32(buffer
);
129 boot_size
= get_le32(buffer
+ 4);
130 if ((boot_offset
& 3) || /*(boot_size & 3) ||*/
131 boot_offset
== 0 || boot_size
== 0) {
132 DPRINTF("Suspicious PREP boot parameters: %08x %08x %08x %08x\n",
133 part
->start
, part
->start
* 0x200, boot_offset
, boot_size
);
138 /* IBM boot blocs respect the norm better than others... */
140 part_seek(part
, 0, 0);
141 if (bd_read(bd
, buffer
, part
->bloc_size
) < 0) {
142 ERROR("%s sector_read failed (%d)\n", __func__
, i
);
146 boot_offset
= get_le32(buffer
);
147 boot_size
= get_le32(buffer
+ 4);
150 DPRINTF("PREP boot parameters: %08x %08x %08x %08x\n",
151 part
->start
, part
->start
* 0x200, boot_offset
, boot_size
);
152 if (boot_size
> (part
->size
* part
->bloc_size
)) {
153 ERROR("PREP boot image greater than boot partition: %0x %0x\n",
154 boot_size
, part
->size
* part
->bloc_size
);
160 part
->boot_start
.bloc
= 0;
161 part
->boot_start
.offset
= 0;
162 part
->boot_size
.bloc
= boot_size
/ part
->bloc_size
;
163 part
->boot_size
.offset
= boot_size
% part
->bloc_size
;
165 part
->boot_entry
= boot_offset
- part
->bloc_size
;
166 part
->flags
= PART_TYPE_PREP
| PART_FLAG_BOOT
;
167 part_register(bd
, part
, "PREP boot");
168 fs_raw_set_bootfile(part
, part
->boot_start
.bloc
,
169 part
->boot_start
.offset
,
170 part
->boot_size
.bloc
,
171 part
->boot_size
.offset
);
173 case 0x63: /* GNU Hurd */
174 goto register_nonboot
;
175 case 0x83: /* Linux */
176 goto register_nonboot
;
177 case 86 ... 87: /* NFTS volume set */
178 /* Not supported by now */
180 case 0x8E: /* Linux LVM */
181 /* Not supported by now */
183 case 0x96: /* AIX seems to use this to identify ISO 9660 'partitions' */
185 case 0xA5: /* FreeBSD */
186 goto register_nonboot
;
187 case 0xA6: /* OpenBSD */
188 goto register_nonboot
;
189 case 0xA7: /* NeXTSTEP */
190 goto register_nonboot
;
191 case 0xA8: /* Darwin UFS */
192 goto register_nonboot
;
193 case 0xA9: /* NetBSD */
194 goto register_nonboot
;
195 case 0xAB: /* Darwin boot */
196 /* Not supported by now */
198 case 0xBE: /* Solaris boot */
199 /* Not supported by now */
201 case 0xEB: /* BeOS fs */
202 goto register_nonboot
;
203 case 0xFD: /* Linux RAID */
204 /* Not supported by now */