Changeset dc76f4a in mainline


Ignore:
Timestamp:
2013-07-29T00:48:51Z (11 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
675de6d
Parents:
c3cbbb2
Message:

libmbr, libgpt polishing

Location:
uspace
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/hdisk/func_gpt.c

    rc3cbbb2 rdc76f4a  
    4242#include "input.h"
    4343
    44 static int set_gpt_partition(tinput_t *, gpt_part_t *);
     44static int set_gpt_partition(tinput_t *, gpt_part_t *, unsigned int);
    4545
    4646int construct_gpt_label(label_t *this)
     
    6868        }
    6969       
    70         return set_gpt_partition(in, p);
     70        return set_gpt_partition(in, p, this->alignment);
    7171}
    7272
     
    8080       
    8181        rc = gpt_remove_partition(this->data.gpt, idx);
    82         if (rc != EOK) {
     82        if (rc == ENOMEM) {
    8383                printf("Warning: running low on memory, not resizing...\n");
    8484                return rc;
     85        } else if (rc == EINVAL) {
     86                printf("Invalid index.\n");
     87                return rc;
    8588        }
    8689       
     
    102105int print_gpt_parts(label_t *this)
    103106{
    104         //int rc;
    105107        printf("Current partition scheme (GPT):\n");
    106         printf("\t\tStart:\tEnd:\tLength:\tType:\tName:\n");
     108        printf("%15s %10s %10s Type: Name:\n", "Start:", "End:", "Length:");
    107109       
    108110        size_t i = 0;
     
    117119                        printf("%15s %10s %10s Type: Name:\n", "Start:", "End:", "Length:");
    118120               
    119                 //printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length,
    120                 //              iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter));
     121               
    121122                printf("%3u  %10llu %10llu %10llu    %3d %s\n", i-1, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
    122123                                gpt_get_end_lba(iter) - gpt_get_start_lba(iter), gpt_get_part_type(iter),
     
    125126        }
    126127       
    127         //return rc;
    128128        return EOK;
    129129}
     
    173173}
    174174
    175 static int set_gpt_partition(tinput_t *in, gpt_part_t *p)
     175static int set_gpt_partition(tinput_t *in, gpt_part_t *p, unsigned int alignment)
    176176{
    177177        int rc;
     
    181181        printf("Set starting address (number): ");
    182182        sa = get_input_uint64(in);
     183        if (sa % alignment != 0)
     184                sa = gpt_get_next_aligned(sa, alignment);
    183185       
    184186        printf("Set end addres (number): ");
  • uspace/app/hdisk/hdisk.c

    rc3cbbb2 rdc76f4a  
    178178                                break;
    179179                        case 'f':
    180                                 free_label();
    181180                                select_label_format(in);
    182181                                break;
  • uspace/lib/gpt/libgpt.c

    rc3cbbb2 rdc76f4a  
    5151#include "libgpt.h"
    5252
    53 static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t *header);
    54 static gpt_partitions_t * alloc_part_array(uint32_t num);
     53static int load_and_check_header(service_id_t, aoff64_t, size_t, gpt_header_t *);
     54static gpt_partitions_t * alloc_part_array(uint32_t);
    5555static int extend_part_array(gpt_partitions_t *);
    5656static int reduce_part_array(gpt_partitions_t *);
    57 static long long nearest_larger_int(double a);
     57//static long long nearest_larger_int(double);
    5858static uint8_t get_byte(const char *);
    59 static int check_overlap(gpt_part_t * p1, gpt_part_t * p2);
     59static bool check_overlap(gpt_part_t *, gpt_part_t *);
    6060
    6161/** Allocate memory for gpt label */
     
    6666                return NULL;
    6767       
     68        /* This is necessary so that gpt_part_foreach does not segfault */
     69        label->parts = gpt_alloc_partitions();
     70        if (label == NULL) {
     71                free(label);
     72                return NULL;
     73        }
     74       
    6875        label->gpt = NULL;
    69         label->parts = NULL;
     76       
    7077        label->device = 0;
    7178       
     
    9299                return NULL;
    93100       
    94         // We might need only sizeof(gpt_header_t),
    95         // but we should follow specs and have
    96         // zeroes through all the rest of the block
     101        /*
     102         * We might need only sizeof(gpt_header_t), but we should follow
     103         * specs and have zeroes through all the rest of the block
     104         */
    97105        size_t final_size = size > sizeof(gpt_header_t) ? size : sizeof(gpt_header_t);
    98106        gpt->header = malloc(final_size);
     
    178186        int rc;
    179187        size_t b_size;
    180 
    181         label->gpt->header->header_crc32 = 0;
    182         label->gpt->header->header_crc32 = compute_crc32((uint8_t *) label->gpt->header,
    183                                         uint32_t_le2host(label->gpt->header->header_size));
    184 
    185         rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
     188       
     189        /* The comm_size argument (the last one) is ignored */
     190        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
    186191        if (rc != EOK && rc != EEXIST)
    187192                return rc;
    188 
     193       
    189194        rc = block_get_bsize(dev_handle, &b_size);
    190195        if (rc != EOK)
    191196                return rc;
    192 
    193         /* Write to main GPT header location */
    194         rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, label->gpt->header);
    195         if (rc != EOK) {
    196                 block_fini(dev_handle);
    197                 return rc;
    198         }
    199 
     197       
    200198        aoff64_t n_blocks;
    201199        rc = block_get_nblocks(dev_handle, &n_blocks);
     
    204202                return rc;
    205203        }
    206 
     204       
     205        uint64_t tmp;
     206       
     207        /* Prepare the backup header */
     208        label->gpt->header->alternate_lba = label->gpt->header->my_lba;
     209        label->gpt->header->my_lba = host2uint64_t_le(n_blocks - 1);
     210       
     211        tmp = label->gpt->header->entry_lba;
     212        label->gpt->header->entry_lba = host2uint64_t_le(n_blocks -
     213            (uint32_t_le2host(label->gpt->header->fillries) * sizeof(gpt_entry_t))
     214            / b_size - 1);
     215       
     216        label->gpt->header->header_crc32 = 0;
     217        label->gpt->header->header_crc32 = host2uint32_t_le(
     218            compute_crc32((uint8_t *) label->gpt->header,
     219                uint32_t_le2host(label->gpt->header->header_size)));
     220       
    207221        /* Write to backup GPT header location */
    208         //FIXME: those idiots thought it would be cool to have these fields in reverse order...
    209222        rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, label->gpt->header);
     223        if (rc != EOK) {
     224                block_fini(dev_handle);
     225                return rc;
     226        }
     227       
     228       
     229        /* Prepare the main header */
     230        label->gpt->header->entry_lba = tmp;
     231       
     232        tmp = label->gpt->header->alternate_lba;
     233        label->gpt->header->alternate_lba = label->gpt->header->my_lba;
     234        label->gpt->header->my_lba = tmp;
     235       
     236        label->gpt->header->header_crc32 = 0;
     237        label->gpt->header->header_crc32 = host2uint32_t_le(
     238            compute_crc32((uint8_t *) label->gpt->header,
     239                uint32_t_le2host(label->gpt->header->header_size)));
     240       
     241        /* Write to main GPT header location */
     242        rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, label->gpt->header);
    210243        block_fini(dev_handle);
    211244        if (rc != EOK)
    212245                return rc;
    213 
     246       
     247       
    214248        return 0;
    215249}
     
    218252gpt_partitions_t * gpt_alloc_partitions()
    219253{
    220         return alloc_part_array(128);
     254        return alloc_part_array(GPT_MIN_PART_NUM);
    221255}
    222256
     
    241275        }
    242276
    243         /* We can limit comm_size like this:
    244          *  - we don't need more bytes
    245          *  - the size of GPT partition entry can be different to 128 bytes */
    246277        /* comm_size is ignored */
    247278        rc = block_init(EXCHANGE_SERIALIZE, label->device, sizeof(gpt_entry_t));
     
    258289        aoff64_t pos = ent_lba * block_size;
    259290
    260         /* Now we read just sizeof(gpt_entry_t) bytes for each entry from the device.
     291        /*
     292         * Now we read just sizeof(gpt_entry_t) bytes for each entry from the device.
    261293         * Hopefully, this does not bypass cache (no mention in libblock.c),
    262294         * and also allows us to have variable partition entry size (but we
    263295         * will always read just sizeof(gpt_entry_t) bytes - hopefully they
    264          * don't break backward compatibility) */
     296         * don't break backward compatibility)
     297         */
    265298        for (i = 0; i < fillries; ++i) {
    266                 //FIXME: this does bypass cache...
     299                /*FIXME: this does bypass cache... */
    267300                rc = block_read_bytes_direct(label->device, pos, sizeof(gpt_entry_t), label->parts->part_array + i);
    268                 //FIXME: but seqread() is just too complex...
    269                 //rc = block_seqread(gpt->device, &bufpos, &buflen, &pos, res->part_array[i], sizeof(gpt_entry_t));
     301                /*
     302                 * FIXME: but seqread() is just too complex...
     303                 * rc = block_seqread(gpt->device, &bufpos, &buflen, &pos, res->part_array[i], sizeof(gpt_entry_t));
     304                 */
    270305                pos += ent_size;
    271306
     
    274309        }
    275310
    276         /* FIXME: so far my boasting about variable partition entry size
     311        /*
     312         * FIXME: so far my boasting about variable partition entry size
    277313         * will not work. The CRC32 checksums will be different.
    278314         * This can't be fixed easily - we'd have to run the checksum
     
    333369                goto fail;
    334370       
     371        uint64_t arr_blocks = (fillries * sizeof(gpt_entry_t)) / b_size;
     372        label->gpt->header->first_usable_lba = host2uint64_t_le(arr_blocks + 1);
     373        label->gpt->header->last_usable_lba = host2uint64_t_le(n_blocks - arr_blocks - 2);
     374       
     375       
    335376        /* Write to backup GPT partition array location */
    336         //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
     377        rc = block_write_direct(dev_handle, n_blocks - arr_blocks - 1,
     378                 arr_blocks, label->parts->part_array);
    337379        if (rc != EOK)
    338380                goto fail;
     
    340382        /* Write to main GPT partition array location */
    341383        rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba),
    342                  nearest_larger_int((uint64_t_le2host(label->gpt->header->entry_size) * fillries) / b_size),
    343                  label->parts->part_array);
     384                 arr_blocks, label->parts->part_array);
    344385        if (rc != EOK)
    345386                goto fail;
     
    442483int gpt_add_partition(gpt_label_t *label, gpt_part_t *partition)
    443484{
    444         if (label->parts->fill == label->parts->arr_size) {
    445                 if (extend_part_array(label->parts) == -1)
    446                         return ENOMEM;
    447         }
    448        
    449         /*FIXME:
    450          * Check dimensions and stuff! */
     485        /* FIXME: Check dimensions! */
    451486        gpt_part_foreach(label, p) {
    452487                if (gpt_get_part_type(p) != GPT_PTE_UNUSED) {
     
    456491        }
    457492       
    458         memcpy(label->parts->part_array + label->parts->fill++,
    459                partition, sizeof(gpt_part_t));
    460        
     493        gpt_part_t *p;
     494        /* Find the first empty entry */
     495        do {
     496                if (label->parts->fill == label->parts->arr_size) {
     497                        if (extend_part_array(label->parts) == -1)
     498                                return ENOMEM;
     499                }
     500               
     501                p = label->parts->part_array + label->parts->fill++;
     502               
     503        } while (gpt_get_part_type(p) != GPT_PTE_UNUSED);
     504       
     505       
     506        memcpy(p, partition, sizeof(gpt_entry_t));
    461507       
    462508       
     
    475521int gpt_remove_partition(gpt_label_t *label, size_t idx)
    476522{
    477         if (idx >= label->parts->fill)
     523        if (idx >= label->parts->arr_size)
    478524                return EINVAL;
    479525       
    480         /* FIXME!
     526        /*
     527         * FIXME!
    481528         * If we allow blank spots, we break the array. If we have more than
    482529         * 128 partitions in the array and then remove something from
    483          * the first 128 partitions, we would forget to write the last one.*/
     530         * the first 128 partitions, we would forget to write the last one.
     531         */
    484532        memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t));
    485533       
    486         label->parts->fill = idx;
    487        
    488         /* FIXME! HOPEFULLY FIXED.
     534        if (label->parts->fill > idx)
     535                label->parts->fill = idx;
     536       
     537        /*
     538         * FIXME! HOPEFULLY FIXED.
    489539         * We cannot reduce the array so simply. We may have some partitions
    490          * there since we allow blank spots. */
     540         * there since we allow blank spots.
     541         */
    491542        gpt_part_t * p;
    492         if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
     543       
     544        if (label->parts->fill > GPT_MIN_PART_NUM &&
     545            label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
    493546                for (p = gpt_get_partition_at(label, label->parts->arr_size / 2);
    494547                     p < label->parts->part_array + label->parts->arr_size; ++p) {
     
    635688}
    636689
     690/** Generate a new pseudo-random UUID
     691 * @param uuid Pointer to the UUID to overwrite.
     692 */
    637693void gpt_set_random_uuid(uint8_t * uuid)
    638694{
     
    645701}
    646702
    647 // Internal functions follow //
     703/** Get next aligned address */
     704uint64_t gpt_get_next_aligned(uint64_t addr, unsigned int alignment)
     705{
     706        uint64_t div = addr / alignment;
     707        return (div + 1) * alignment;
     708}
     709
     710/* Internal functions follow */
    648711
    649712static int load_and_check_header(service_id_t dev_handle, aoff64_t addr, size_t b_size, gpt_header_t * header)
     
    686749                return NULL;
    687750        }
    688 
     751       
    689752        uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
    690753        res->part_array = malloc(size * sizeof(gpt_entry_t));
     
    694757                return NULL;
    695758        }
    696 
     759       
     760        memset(res->part_array, 0, size * sizeof(gpt_entry_t));
     761       
    697762        res->fill = 0;
    698763        res->arr_size = num;
     
    727792                        return ENOMEM;
    728793
    729                 memcpy(tmp, p->part_array, p->fill < nsize ? p->fill  : nsize);
     794                memcpy(tmp, p->part_array, p->fill < nsize ? p->fill : nsize);
    730795                free(p->part_array);
    731796                p->part_array = tmp;
     
    736801}
    737802
    738 //FIXME: replace this with a library call, if it exists
    739 static long long nearest_larger_int(double a)
     803/*static long long nearest_larger_int(double a)
    740804{
    741805        if ((long long) a == a) {
     
    744808
    745809        return ((long long) a) + 1;
    746 }
    747 
     810}*/
     811
     812/* Parse a byte from a string in hexadecimal
     813 * i.e., "FF" => 255
     814 */
    748815static uint8_t get_byte(const char * c)
    749816{
     
    755822}
    756823
    757 static int check_overlap(gpt_part_t * p1, gpt_part_t * p2)
     824static bool check_overlap(gpt_part_t * p1, gpt_part_t * p2)
    758825{
    759826        if (gpt_get_start_lba(p1) < gpt_get_start_lba(p2) && gpt_get_end_lba(p1) <= gpt_get_start_lba(p2)) {
    760                 return 0;
     827                return false;
    761828        } else if (gpt_get_start_lba(p1) > gpt_get_start_lba(p2) && gpt_get_end_lba(p2) <= gpt_get_start_lba(p1)) {
    762                 return 0;
    763         }
    764 
    765         return 1;
    766 }
    767 
    768 
     829                return false;
     830        }
     831
     832        return true;
     833}
     834
     835
  • uspace/lib/gpt/libgpt.h

    rc3cbbb2 rdc76f4a  
    3434 */
    3535
    36 #ifndef __GPT_H__
    37 #define __GPT_H__
     36#ifndef LIBGPT_LIBGPT_H_
     37#define LIBGPT_LIBGPT_H_
    3838
    3939#define LIBGPT_NAME     "libgpt"
     
    4141#include <loc.h>
    4242#include <sys/types.h>
     43
     44#include "gpt.h"
    4345
    4446/** Block address of GPT header. */
     
    5961extern const uint8_t efi_signature[8];
    6062
    61 typedef enum {
    62         AT_REQ_PART = 0,
    63         AT_NO_BLOCK_IO,
    64         AT_LEGACY_BOOT,
    65         AT_UNDEFINED,
    66         AT_SPECIFIC = 48
    67 } GPT_ATTR;
    68 
    69 /** GPT header
    70  * - all in little endian.
    71  */
    72 typedef struct {
    73         uint8_t  efi_signature[8];
    74         uint32_t revision;
    75         uint32_t header_size;
    76         uint32_t header_crc32;
    77         uint32_t reserved;
    78         uint64_t my_lba;
    79         uint64_t alternate_lba;
    80         uint64_t first_usable_lba;
    81         uint64_t last_usable_lba;
    82         uint8_t  disk_guid[16];
    83         uint64_t entry_lba;
    84         uint32_t fillries;
    85         uint32_t entry_size;
    86         uint32_t pe_array_crc32;
    87 } __attribute__((packed)) gpt_header_t;
    88 
    8963typedef struct {
    9064        /** Raw header. Has more bytes alloced than sizeof(gpt_header_t)!
     
    9367} gpt_t;
    9468
    95 /** GPT partition entry */
    96 typedef struct {
    97         uint8_t part_type[16];
    98         uint8_t part_id[16];
    99         uint64_t start_lba;
    100         uint64_t end_lba;
    101         uint64_t attributes;
    102         uint8_t part_name[72];
    103 } __attribute__((packed)) gpt_entry_t;
    104 
    105 
    106 //typedef struct g_part {
    107         ///** Partition entry is in use **/
    108         //bool present;
    109         ///** Address of first block */
    110         //aoff64_t start_addr;
    111         ///** Number of blocks */
    112         //aoff64_t length;
    113         ///** Raw data access */
    114         //gpt_entry_t raw_data; //TODO: a pointer or just a member?
    115 //}gpt_part_t;
    11669typedef gpt_entry_t gpt_part_t;
    117 
    11870
    11971typedef struct gpt_parts {
     
    168120
    169121extern void            gpt_set_random_uuid(uint8_t *);
     122extern uint64_t        gpt_get_next_aligned(uint64_t, unsigned int);
    170123
    171124
  • uspace/lib/mbr/libmbr.c

    rc3cbbb2 rdc76f4a  
    4242#include <stdio.h>
    4343#include <stdlib.h>
     44#include <str_error.h>
    4445
    4546#include "libmbr.h"
     
    4950static int decode_logical(mbr_label_t *, mbr_part_t *);
    5051static void encode_part(mbr_part_t *, pt_entry_t *, uint32_t, bool);
    51 static int check_overlap(mbr_part_t *, mbr_part_t *);
    52 static int check_encaps(mbr_part_t *, mbr_part_t *);
    53 static int check_preceeds(mbr_part_t *, mbr_part_t *);
    54 static mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p);
    55 static mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p);
     52static bool check_overlap(mbr_part_t *, mbr_part_t *);
     53static bool check_encaps(mbr_part_t *, mbr_part_t *);
     54static bool check_preceeds(mbr_part_t *, mbr_part_t *);
     55static mbr_err_val mbr_add_primary(mbr_label_t *, mbr_part_t *);
     56static mbr_err_val mbr_add_logical(mbr_label_t *, mbr_part_t *);
    5657
    5758/** Allocate and initialize mbr_label_t structure */
     
    759760/** Check whether two partitions overlap
    760761 *
    761  * @return              1 for yes, 0 for no
    762  */
    763 static int check_overlap(mbr_part_t * p1, mbr_part_t * p2)
     762 * @return              true/false
     763 */
     764static bool check_overlap(mbr_part_t * p1, mbr_part_t * p2)
    764765{
    765766        if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length <= p2->start_addr) {
    766                 return 0;
     767                return false;
    767768        } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length <= p1->start_addr) {
    768                 return 0;
    769         }
    770 
    771         return 1;
     769                return false;
     770        }
     771
     772        return true;
    772773}
    773774
    774775/** Check whether one partition encapsulates the other
    775776 *
    776  * @return              1 for yes, 0 for no
    777  */
    778 static int check_encaps(mbr_part_t * inner, mbr_part_t * outer)
     777 * @return              true/false
     778 */
     779static bool check_encaps(mbr_part_t * inner, mbr_part_t * outer)
    779780{
    780781        if (inner->start_addr <= outer->start_addr || outer->start_addr + outer->length <= inner->start_addr) {
    781                 return 0;
     782                return false;
    782783        } else if (outer->start_addr + outer->length < inner->start_addr + inner->length) {
    783                 return 0;
    784         }
    785 
    786         return 1;
     784                return false;
     785        }
     786
     787        return true;
    787788}
    788789
    789790/** Check whether one partition preceeds the other
    790791 *
    791  * @return              1 for yes, 0 for no
    792  */
    793 static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee)
     792 * @return              true/false
     793 */
     794static bool check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee)
    794795{
    795796        return preceeder->start_addr < precedee->start_addr;
  • uspace/lib/mbr/libmbr.h

    rc3cbbb2 rdc76f4a  
    3838
    3939#include <sys/types.h>
     40#include "mbr.h"
    4041
    4142#define LIBMBR_NAME     "libmbr"
    42 
    43 #ifdef DEBUG_CONFIG
    44 #include <stdio.h>
    45 #include <str_error.h>
    46 #define DEBUG_PRINT_0(str) \
    47         printf("%s:%d: " str, __FILE__, __LINE__)
    48 #define DEBUG_PRINT_1(str, arg1) \
    49         printf("%s:%d: " str, __FILE__, __LINE__, arg1)
    50 #define DEBUG_PRINT_2(str, arg1, arg2) \
    51         printf("%s:%d: " str, __FILE__, __LINE__, arg1, arg2)
    52 #define DEBUG_PRINT_3(str, arg1, arg2, arg3) \
    53         printf("%s:%d: " str, __FILE__, __LINE__, arg1, arg2, arg3)
    54 #else
    55 #define DEBUG_PRINT_0(str)
    56 #define DEBUG_PRINT_1(str, arg1)
    57 #define DEBUG_PRINT_2(str, arg1, arg2)
    58 #define DEBUG_PRINT_3(str, arg1, arg2, arg3)
    59 #endif
    60 
    61 /** Number of primary partition records */
    62 #define N_PRIMARY               4
    63 
    64 /** Boot record signature */
    65 #define BR_SIGNATURE    0xAA55
    66 
    67 enum {
    68         /** Non-bootable */
    69         B_INACTIVE = 0x00,
    70         /** Bootable */
    71         B_ACTIVE = 0x80,
    72         /** Anything else means invalid */
    73 };
    7443
    7544typedef enum {
     
    8049        ST_LOGIC = 8
    8150} MBR_FLAGS;
    82 
    83 enum {
    84         /** Unused partition entry */
    85         PT_UNUSED       = 0x00,
    86         /** Extended partition */
    87         PT_EXTENDED     = 0x05,
    88         /** Extended partition with LBA */
    89         PT_EXTENDED_LBA = 0x0F,
    90         /** GPT Protective partition */
    91         PT_GPT  = 0xEE,
    92 };
    9351
    9452typedef enum {
     
    11270        ERR_LIBBLOCK,
    11371} mbr_err_val;
    114 
    115 
    116 /** Structure of a partition table entry */
    117 typedef struct {
    118         uint8_t status;
    119         /** CHS of fist block in partition */
    120         uint8_t first_chs[3];
    121         /** Partition type */
    122         uint8_t ptype;
    123         /** CHS of last block in partition */
    124         uint8_t last_chs[3];
    125         /** LBA of first block in partition */
    126         uint32_t first_lba;
    127         /** Number of blocks in partition */
    128         uint32_t length;
    129 } __attribute__((packed)) pt_entry_t;
    130 
    131 /** Structure of a boot-record block */
    132 typedef struct {
    133         /** Area for boot code */
    134         uint8_t code_area[440];
    135         /** Optional media ID */
    136         uint32_t media_id;
    137         /** Padding */
    138         uint16_t pad0;
    139         /** Partition table entries */
    140         pt_entry_t pte[N_PRIMARY];
    141         /** Boot record block signature (@c BR_SIGNATURE) */
    142         uint16_t signature;
    143 } __attribute__((packed)) br_block_t;
    14472
    14573/** MBR header */
Note: See TracChangeset for help on using the changeset viewer.