int read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) { struct partition p; unsigned long offset = all.start; int i, n=4; unsigned char *bp; uint64_t sector_size_mul = get_sector_size(fd)/512; bp = (unsigned char *)getblock(fd, offset); if (bp == NULL) return -1; if (bp[510] != 0x55 || bp[511] != 0xaa) return -1; for (i=0; i<4; i++) { memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); if (is_gpt(p.sys_type)) return 0; if (i < ns) { sp[i].start = sector_size_mul * le32_to_cpu(p.start_sect); sp[i].size = sector_size_mul * le32_to_cpu(p.nr_sects); } else { fprintf(stderr, "dos_partition: too many slices\n"); break; } if (is_extended(p.sys_type)) { /* extended partitions only get one or two sectors mapped for LILO to install, whichever is needed to have 1kb of space */ if (sector_size_mul == 1) sp[i].size = 2; else sp[i].size = sector_size_mul; n += read_extended_partition(fd, &p, i, sp+n, ns-n); } } return n; }
int read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) { struct partition *p; unsigned long offset = all.start; int i, n=0; unsigned char *bp; bp = getblock(fd, offset); if (bp == NULL) return -1; if (bp[510] != 0x55 || bp[511] != 0xaa) return -1; p = (struct partition *) (bp + 0x1be); for (i=0; i<4; i++) { /* always add, even if zero length */ if (n < ns) { sp[n].start = p->start_sect; sp[n].size = p->nr_sects; n++; } else { fprintf(stderr, "dos_partition: too many slices\n"); break; } p++; } p = (struct partition *) (bp + 0x1be); for (i=0; i<4; i++) { if (is_extended(p->sys_type)) n += read_extended_partition(fd, p, sp+n, ns-n); p++; } return n; }
/* * read_mbr -- * reads Master Boot Record (sector 0) of physical device and * constructs disk description structure * * PARAMETERS: * disk_desc - returned disc description structure * * RETURNS: * RTEMS_SUCCESSFUL if success, * RTEMS_INTERNAL_ERROR otherwise */ static rtems_status_code read_mbr(int fd, rtems_disk_desc_t *disk_desc) { int part_num; rtems_sector_data_t *sector = NULL; rtems_part_desc_t *part_desc; uint8_t *data; rtems_status_code rc; /* get MBR sector */ rc = get_sector(fd, 0, §or); if (rc != RTEMS_SUCCESSFUL) { if (sector) free(sector); return rc; } /* check if the partition table structure is MS-DOS style */ if (!msdos_signature_check(sector)) { free(sector); return RTEMS_INTERNAL_ERROR; } /* read and process 4 primary partition descriptors */ data = sector->data + RTEMS_IDE_PARTITION_TABLE_OFFSET; for (part_num = 0; part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER; part_num++) { rc = data_to_part_desc(data, &part_desc); if (rc != RTEMS_SUCCESSFUL) { free(sector); return rc; } if (part_desc != NULL) { part_desc->log_id = part_num + 1; part_desc->disk_desc = disk_desc; part_desc->end = part_desc->start + part_desc->size - 1; disk_desc->partitions[part_num] = part_desc; } else { disk_desc->partitions[part_num] = NULL; } data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE; } free(sector); disk_desc->last_log_id = RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER; /* There cannot be more than one extended partition, but we are to process each primary partition */ for (part_num = 0; part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER; part_num++) { part_desc = disk_desc->partitions[part_num]; if (part_desc != NULL && is_extended(part_desc->sys_type)) { read_extended_partition(fd, part_desc->start, part_desc); free(part_desc); disk_desc->partitions[part_num] = NULL; } } return RTEMS_SUCCESSFUL; }
/* * read_extended_partition -- * recursively reads extended partition sector from the device * and constructs the partition table tree * * PARAMETERS: * fd - file descriptor * start - start sector of primary extended partition, used for * calculation of absolute partition sector address * ext_part - description of extended partition to process * * RETURNS: * RTEMS_SUCCESSFUL if success, * RTEMS_NO_MEMOTY if cannot allocate memory for part_desc_t strucure, * RTEMS_INTERNAL_ERROR if other error occurs. */ static rtems_status_code read_extended_partition(int fd, uint32_t start, rtems_part_desc_t *ext_part) { int i; rtems_sector_data_t *sector = NULL; uint32_t here; uint8_t *data; rtems_part_desc_t *new_part_desc; rtems_status_code rc; if ((ext_part == NULL) || (ext_part->disk_desc == NULL)) { return RTEMS_INTERNAL_ERROR; } /* get start sector of current extended partition */ here = ext_part->start; /* get first extended partition sector */ rc = get_sector(fd, here, §or); if (rc != RTEMS_SUCCESSFUL) { if (sector) free(sector); return rc; } if (!msdos_signature_check(sector)) { free(sector); return RTEMS_INTERNAL_ERROR; } /* read and process up to 4 logical partition descriptors */ data = sector->data + RTEMS_IDE_PARTITION_TABLE_OFFSET; for (i = 0; i < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER; i++) { /* if data_to_part_desc fails skip this partition * and parse the next one */ rc = data_to_part_desc(data, &new_part_desc); if (rc != RTEMS_SUCCESSFUL) { free(sector); return rc; } if (new_part_desc == NULL) { data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE; continue; } ext_part->sub_part[i] = new_part_desc; new_part_desc->ext_part = ext_part; new_part_desc->disk_desc = ext_part->disk_desc; if (is_extended(new_part_desc->sys_type)) { new_part_desc->log_id = EMPTY_PARTITION; new_part_desc->start += start; read_extended_partition(fd, start, new_part_desc); } else { rtems_disk_desc_t *disk_desc = new_part_desc->disk_desc; disk_desc->partitions[disk_desc->last_log_id] = new_part_desc; new_part_desc->log_id = ++disk_desc->last_log_id; new_part_desc->start += here; new_part_desc->end = new_part_desc->start + new_part_desc->size - 1; } data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE; } free(sector); return RTEMS_SUCCESSFUL; }