| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 
 | /* 
 * 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"))));
    }
}
 |