| /* |
| * 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")))); |
| } |
| } |
| |