| /* |
| * 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; |
| unsigned 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 >= (2 * (GB / 512))) { /* weird () to quiet compiler */ |
| printf("NOTE: Extended partition %d might be beyond reach of IPL\r\n", |
| extnum + 1); |
| } |
| |
| fb.dosmagic[0] = 0; // wipe dosmagic flag just to be on the safe side |
| if (seekread(bootdev, (char *)&fb, sizeof fb, 512ULL * offset) == -1) { |
| 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 = __le32_to_cpu(ptab[0].start_sect) + offset; |
| mptab[extnum].length = __le32_to_cpu(ptab[0].nr_sects); |
| mptab[extnum].id = ptab[0].sys_ind; |
| |
| offset = mptab[extnum].start + __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; |
| |
| printf("Partition Start(MB) End(MB) Id Type\n\r"); |
| for (i = 0; i < maxparts; i++) |
| { |
| if (mptab[i].id != 0 && ! is_extended(mptab[i].id)) |
| printf("%-9x %8d %7d %3x %s\n\r", |
| i + 1, |
| 1 + (mptab[i].start >> mbshift), |
| (mptab[i].start + mptab[i].length) >> mbshift, |
| mptab[i].id, |
| mptab[i].id == LINUX_EXT2_PARTITION ? "ext2" : |
| (mptab[i].id == LINUX_SWAP_PARTITION ? "swap" : |
| (mptab[i].id == LINUX_RAID_PARTITION ? "RAID" : |
| (mptab[i].id == PALO_PARTITION ? "Palo" : "Unknown")))); |
| } |
| } |
| |