blob: 8f3de8a6270dc62be958c38670f93cb679a9fcd8 [file] [log] [blame]
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com
*/
#include "common.h"
#include <stdio.h>
int
is_extended(int id)
{
switch(id)
{
case DOS_EXTENDED_PARTITION:
case LINUX_EXTENDED_PARTITION:
case WIN98_EXTENDED_PARTITION:
return 1;
}
return 0;
}
int
load_partitions(int bootdev, struct diskpartition *mptab, int maxparts)
{
struct firstblock fb;
struct partition *ptab = &fb.part[0];
int i;
int ex = -1;
int extnum = 4;
__u64 offset;
/* seekread MBR */
if (seekread(bootdev, (char *)&fb, sizeof fb, 0) == -1)
return 0;
if (fb.dosmagic[0] != 0x55 || fb.dosmagic[1] != 0xaa)
return 0;
for (i = 0; i < 4; i++)
{
mptab[i].start = __le32_to_cpu(ptab[i].start_sect);
mptab[i].length = __le32_to_cpu(ptab[i].nr_sects);
mptab[i].id = ptab[i].sys_ind;
if (is_extended(ptab[i].sys_ind))
ex = i;
}
if (ex != -1)
{
offset = mptab[ex].start;
while (extnum < maxparts)
{
if (disk_2gb_limit && ((offset * 512) >> 31)) {
// printf("NOTE: Extended partition %d is beyond reach of IPL\r\n", extnum + 1);
break;
}
fb.dosmagic[0] = 0; // wipe dosmagic flag just to be on the safe side
if (seekread(bootdev, (char *)&fb, sizeof fb, 512 * offset) < 0) {
// printf("seekread(bootdev,..., 512 * 0x%x) failed!\n\r", offset);
break;
}
if (fb.dosmagic[0] != 0x55 || fb.dosmagic[1] != 0xaa)
{
// Seems to not be an extended partition, so exit.
break;
}
mptab[extnum].start = offset + (__u32)__le32_to_cpu(ptab[0].start_sect);
mptab[extnum].length = (__u32) __le32_to_cpu(ptab[0].nr_sects);
mptab[extnum].id = ptab[0].sys_ind;
offset = mptab[ex].start + (__u32) __le32_to_cpu(ptab[1].start_sect);
extnum++;
if (!is_extended(ptab[1].sys_ind))
break;
}
}
return 1;
}
void
print_ptab_pretty(struct diskpartition *mptab, int maxparts)
{
int i;
const int mbshift = 20 - 9;
const int gbshift = 30 - 9;
printf("Partition Start End Sectors Size Id Type\n\r");
for (i = 0; i < maxparts; i++)
{
unsigned int gb = (mptab[i].length >> gbshift);
if (mptab[i].id != 0 && ! is_extended(mptab[i].id))
printf("%-8x %9lld %9lld %9lld %5d%c %02x %s\n\r",
i + 1,
mptab[i].start,
mptab[i].start + mptab[i].length - 1,
mptab[i].length,
gb ? : (unsigned) (mptab[i].length >> mbshift),
gb ? 'G' : 'M',
mptab[i].id,
mptab[i].id == LINUX_EXT2_PARTITION ? "Linux" :
(mptab[i].id == LINUX_SWAP_PARTITION ? "swap" :
(mptab[i].id == LINUX_RAID_PARTITION ? "RAID" :
(mptab[i].id == PALO_PARTITION ? "Palo" : "Unknown"))));
}
}