Changeset 440b0ce in mainline


Ignore:
Timestamp:
2009-09-01T20:34:33Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e27b89a
Parents:
822d22a
Message:

Add support for logical partitions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/part/mbr_part/mbr_part.c

    r822d22a r440b0ce  
    3838 * and provides one for each partition.
    3939 *
     40 * Limitations:
     41 *
    4042 * Only works with boot records using LBA. CHS-only records are not
    41  * supported. Only primary partition records are supported.
     43 * supported. Maximum number of partitions is fixed.
    4244 */
    4345
     
    6769
    6870        /** Boot record signature */
    69         BR_SIGNATURE    = 0xAA55
     71        BR_SIGNATURE    = 0xAA55,
     72
     73        /** Maximum number of partitions */
     74        MAX_PART        = 64
     75};
     76
     77enum ptype {
     78        /** Extended partition */
     79        PT_EXTENDED     = 0x05
    7080};
    7181
     
    8797        /** CHS of fist block in partition */
    8898        uint8_t first_chs[3];
     99        /** Partition type */
     100        uint8_t ptype;
    89101        /** CHS of last block in partition */
    90102        uint8_t last_chs[3];
    91         /** Partition type */
    92         uint8_t ptype;
    93103        /** LBA of first block in partition */
    94104        uint32_t first_lba;
     
    120130static dev_handle_t indev_handle;
    121131
    122 static part_t primary[N_PRIMARY];
     132static part_t primary[MAX_PART];
    123133
    124134static int mbr_init(const char *dev_name);
    125135static int mbr_part_read(void);
     136static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
    126137static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall);
    127138static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf);
     
    129140static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba);
    130141
     142/** Total number of partitions entries in @c primary (including non-present). */
     143static int total_part;
    131144
    132145int main(int argc, char **argv)
     
    196209
    197210        /* Create partition devices. */
    198         for (i = 0; i < N_PRIMARY; ++i) {
     211        for (i = 0; i < total_part; ++i) {
    199212                /* Skip absent partitions. */
    200213                if (!primary[i].present)
     
    228241{
    229242        int i, rc;
    230         br_block_t *mbr;
     243        br_block_t *brb;
    231244        uint16_t sgn;
    232         uint32_t sa, len;
    233 
    234         rc = block_bb_read(indev_handle, 0);
     245        uint32_t ba;
     246        part_t *ext_part, cp;
     247        uint32_t base;
     248
     249        brb = malloc(sizeof(br_block_t));
     250        if (brb == NULL) {
     251                printf(NAME ": Failed allocating memory.\n");
     252                return ENOMEM; 
     253        }
     254
     255        /*
     256         * Read primary partition entries.
     257         */
     258
     259        rc = block_read_direct(indev_handle, 0, 1, brb);
    235260        if (rc != EOK) {
    236261                printf(NAME ": Failed reading MBR block.\n");
     
    238263        }
    239264
    240         mbr = block_bb_get(indev_handle);
    241         sgn = uint16_t_le2host(mbr->signature);
    242 
     265        sgn = uint16_t_le2host(brb->signature);
    243266        if (sgn != BR_SIGNATURE) {
    244267                printf(NAME ": Invalid boot record signature 0x%04X.\n", sgn);
     
    246269        }
    247270
     271        ext_part = NULL;
     272
    248273        for (i = 0; i < N_PRIMARY; ++i) {
    249                 sa  = uint32_t_le2host(mbr->pte[i].first_lba);
    250                 len = uint32_t_le2host(mbr->pte[i].length);
    251 
    252                 primary[i].start_addr = sa;
    253                 primary[i].length = len;
    254 
    255                 primary[i].present = (sa != 0 || len != 0) ? true : false;
    256                 primary[i].dev = 0;
    257         }
     274                mbr_pte_to_part(0, &brb->pte[i], &primary[i]);
     275
     276                if (brb->pte[i].ptype == PT_EXTENDED) {
     277                        primary[i].present = false;
     278                        ext_part = &primary[i];
     279                }
     280        }
     281
     282        if (ext_part == NULL)
     283                return EOK;
     284
     285        printf("Extended partition found.\n");
     286
     287        /*
     288         * Read extended partition entries.
     289         */
     290
     291        cp.start_addr = ext_part->start_addr;
     292        cp.length = ext_part->length;
     293        base = ext_part->start_addr;
     294
     295        do {
     296                /*
     297                 * Addressing in the EBR chain is relative to the beginning
     298                 * of the extended partition.
     299                 */
     300                ba = cp.start_addr;
     301                rc = block_read_direct(indev_handle, ba, 1, brb);
     302                if (rc != EOK) {
     303                        printf(NAME ": Failed reading EBR block at %u.\n", ba);
     304                        return rc;
     305                }
     306
     307                sgn = uint16_t_le2host(brb->signature);
     308                if (sgn != BR_SIGNATURE) {
     309                        printf(NAME ": Invalid boot record signature 0x%04X "
     310                            " in EBR at %u.\n", sgn, ba);
     311                        return EINVAL;
     312                }
     313
     314                /* First PTE is the logical partition itself. */
     315                mbr_pte_to_part(base, &brb->pte[0], &primary[i]);
     316                ++i;
     317
     318                /* Second PTE describes next chain element. */
     319                mbr_pte_to_part(base, &brb->pte[1], &cp);
     320        } while (cp.present && i < MAX_PART);
     321
     322        total_part = i;
    258323
    259324        return EOK;
     325}
     326
     327/** Parse partition table entry. */
     328static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part)
     329{
     330        uint32_t sa, len;
     331
     332        sa = uint32_t_le2host(pte->first_lba);
     333        len = uint32_t_le2host(pte->length);
     334
     335        part->start_addr = base + sa;
     336        part->length     = len;
     337
     338        part->present = (sa != 0 || len != 0) ? true : false;
     339        part->dev = 0;
    260340}
    261341
     
    280360        /* Determine which partition device is the client connecting to. */
    281361        pidx = -1;
    282         for (i = 0; i < N_PRIMARY; i++)
     362        for (i = 0; i < total_part; i++)
    283363                if (primary[i].dev == dh)
    284364                        pidx = i;
Note: See TracChangeset for help on using the changeset viewer.